*본 내용은 [Do it! 자바 프로그래밍 입문] 책과 강의를 보고 공부하면서 요점 정리한 내용입니다.
메서드 | 설명 |
---|---|
String toString() | 객체를 문자열로 표현하여 반환합니다. 재정의하여 객체에 대한 설명이나 특정 멤버 변수 값을 반환합니다. |
boolean equals(Object obj) | 두 인스턴스가 동일한지 여부를 반환합니다. 재정의하여 논리적으로 동일한 인스턴스임을 정의할 수 있습니다. |
int hashCode() | 객체의 해시 코드 값을 반환합니다. |
Object clone() | 객체를 복제하여 동일한 멤버 변수 값을 가진 새로운 인스턴스를 생성합니다. |
Class getClass() | 객체의 Class 클래스를 반환합니다. (final로 선언됨) |
void finalize() | 인스턴스가 힙 메모리에서 제거될 때 가비지 컬렉터(GC)에 의해 호출되는 메서드입니다. 네트워크 연결 해제, 열려 있는 파일 스트링 해제 등을 구현합니다. (final로 선언됨) |
void wait() | 멀티스레드 프로그램에서 사용하는 메서드입니다. 스레드를 '기다리는 상태(non runnable)로 만듭니다. (final로 선언됨) |
void notify() | wait()메서드에 의해 기다리고 있는 스레드(non runnable 상태)를 실행 가능한 상태(runnable)로 가져옵니다. (final로 선언됨) |
getClass().getName() + '@' + Integer.toHexString(hashCode())
클래스이름 @ 해시코드값
Object.Book@16f65612
ToStringEx.java
package object;
class Book{
String title;
String author;
Book(String title, String author){
this.title = title;
this.author = author;
}
@Override //toString 재정의하기
public String toString() {
return title + "," + author;
}
}
public class ToStringEx {
public static void main(String[] args) {
Book book = new Book("두잇자바", "은종님");
System.out.println(book);
String str = new String("test");
System.out.println(str);
}
}
재정의 하기 전 실행 결과
object.Book@1d81eb93
test
재정의 한 뒤 실행 결과
두잇자바,은종님
test
EqualsTest.java
package object;
class Student{
int studentID;
String studentName;
Student(int studentID, String studentName){
this.studentID = studentID;
this.studentName = studentName;
}
@Override // equals 재정의하기
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student std = (Student)obj;
if(studentID == std.studentID)
return true;
else
return false;
}
return false;
}
}
public class EqualsTest {
public static void main(String[] args) {
String str1 = new String("test");
String str2 = new String("test");
System.out.println(str1 == str2); // 인스턴스의 힙 메모리 주소가 각각 다르므로
System.out.println(str1.equals(str2)); // String에서 재정의 됨. 문자열이 같은지 확인
Student std1 = new Student(10001, "Tomas");
Student std2 = new Student(10001, "Tomas");
System.out.println(std1 == std2);
System.out.println(std1.equals(std2));
}
}
재정의 하기 전 실행 결과
false
true
false
false
재정의 한 뒤 실행 결과
false
true
false
true
저장위치 = 해시함수 객체정보
index = hash(key)
EqualsTest.java
package object;
class Student{
int studentID;
String studentName;
Student(int studentID, String studentName){
this.studentID = studentID;
this.studentName = studentName;
}
@Override // equals 재정의하기
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student std = (Student)obj;
if(studentID == std.studentID)
return true;
else
return false;
}
return false;
}
// hashCode 재정의하기
public int hashCode() {
return studentID; // 주로 equals를 재정의할 때 쓰인 멤버 변수를 가져다 사용
}
}
public class EqualsTest {
public static void main(String[] args) {
String str1 = new String("test");
String str2 = new String("test");
Student std1 = new Student(10001, "Tomas");
Student std2 = new Student(10001, "Tomas");
//String 인스턴스 hashCode()함수 호출-->같은 값 출력됨
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
//String 인스턴스 해시코드 값 출력하기
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));
//Student 인스턴스 hashCode()함수 호출-->다른 해시코드 값 출력됨
System.out.println(std1.hashCode());
System.out.println(std2.hashCode());
//identityHashCode()는 해시코드 값 return하는 함수이다.
System.out.println(System.identityHashCode(std2));
}
}
재정의 하기 전 실행 결과
3556498 //String 인스턴스 hashCode()함수 호출
3556498
495053715 //String 인스턴스 해시코드 값 출력하기
1922154895
883049899 //Student 인스턴스 hashCode()함수 호출
2093176254
2093176254
재정의 한 뒤 실행 결과
3556498
3556498
495053715
1922154895
10001 //Student 인스턴스 hashCode()함수 호출-->재정의로 같은 값 출력됨
10001
883049899
implements Cloneable
작성해주지 않으면 오류 발생ObjectCloneTest.java
package object;
class Point{
int x;
int y;
Point(int x, int y){
this.x = x;
this.y = y;
}
public String toString() {
return "x=" + x + "," + "y=" + y;
}
}
class Circle implements Cloneable{ // implements Cloneable 써주지 않으면 오류 발생
Point point;
private int radius;
public Circle(int x, int y, int radius) {
point = new Point(x, y);
this.radius = radius;
}
public String toString() {
return "원점은 " + this.point + "이고, 반지름은 " + radius + "입니다.";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class ObjectCloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
// 클론할 때 클론할 수 없을 때의 예외처리
Circle circle = new Circle(10, 20, 5);
Circle cloneCircle = (Circle)circle.clone();
System.out.println(System.identityHashCode(circle));
System.out.println(System.identityHashCode(cloneCircle));
System.out.println(circle);
System.out.println(cloneCircle);
}
}
실행 결과
1922154895
883049899
원점은 x=10,y=20이고, 반지름은 5입니다.
원점은 x=10,y=20이고, 반지름은 5입니다.
서로 다른 해시코드 값 가진 인스턴스 만들어짐
String str1 = new String("abc"); // 생성자의 매개변수로 문자열 생성
String str2 = "test"; // 문자열 상수를 가리키는 방식
(어딘가에 있는 "test"의 주소를 가리키게 됨)
StringTest.java
package string;
public class StringTest {
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2);
String str3 = "abc";
String str4 = "abc";
System.out.println(str3 == str4);
}
}
실행 결과
false
true
StringTest.java
package string;
public class StringTest {
public static void main(String[] args) {
String str1 = new String("java");
String str2 = new String("android");
System.out.println(System.identityHashCode(str1));
str1 = str1.concat(str2);
//str1에 str2가 붙은게 아니라 javaandroid 연결된 새로운 메모리가 생성되어 그 문자열을 가리키게 됨
System.out.println(str1);
System.out.println(System.identityHashCode(str1));
}
}
실행 결과
1313922862
javaandroid
495053715 // 다른 메모리값 출력된다.
StringBuilderTest.java
package string;
public class StringBuilderTest {
public static void main(String[] args) {
String str1 = new String("java");
System.out.println(System.identityHashCode(str1));
StringBuilder buffer = new StringBuilder(str1);
System.out.println(System.identityHashCode(buffer));
buffer.append(" and");
buffer.append(" android");
System.out.println(System.identityHashCode(buffer));
String str2 = buffer.toString();
System.out.println(str2);
}
}
실행 결과
1313922862
495053715
495053715 //같은 값
java and android
기본형 | Wrapper 클래스 |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
Integer는 객체이고, int는 4바이트 기본 자료형임
두 개의 자료를 같이 연산할 때 자동으로 변환이 일어남
자바5.0 이전엔 Integer와 int를 더할 수 없었음. 5.0 이후엔 자동으로 컴파일러가 해줌
Integer num1 = new Integer(100);
int num2 = 200;
int sum = num + num2; // num이 num.intValue()로 변환(언박싱)
Integer num3 = num2; // num2가 integer.valueOf(num2)로 변환(오토박싱)
Integer i = new Integer(100); // 이 생성자 9.0 이후부터 자바에서 쓰지 않을 예정이므로
Integer i = 100; // 다음과 같이 사용을 권장
1. Object 클래스의 getClass()메서드 사용하기
이미 인스턴스가 있는 경우.
getClass()는 Class 클래스를 반환해준다.
String s = new String();
Class c = s.getClass(); // getClass()메서드의 반환형은 Class
2. 클래스 파일 이름을 Class 변수에 직접 대입하기
Class c = String.Class;
3. Class.forName("클래스 이름")메서드 사용하기
클래스 이름을 String으로 가져와서 클래스를 메모리에 올리는 메서드(동적로딩)
1,2 방법의 경우 해당 클래스가 컴파일되어있어야 사용 가능(static로딩). 하지만 forName 사용하는 경우 해당 이름을 가진 클래스가 있으면 메모리에 로딩시킨다(동적로딩).
자주 사용하는 방법이니 알아두자.
Class c = Class.forName("java.lang.String");
reflection 프로그래밍
동적 로딩
이란?[예제1]
Person.java
package classex;
public class Person {
String name;
int age;
public Person() {}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
ClassTest.java
package classex;
public class ClassTest {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Person();
Class pClass1 = person.getClass(); // getClass()는 Object의 메서드이다.
System.out.println(pClass1.getName()); // getName이 Person클래스의 이름 가져옴
Class pClass2 = Person.class;
System.out.println(pClass2.getName());
Class pClass3 = Class.forName("classex.Person"); // 없는 클래스를 찾는 상황을 대비해 에러 처리 해준다.
System.out.println(pClass3.getName());
}
}
실행 결과
classex.Person
classex.Person
classex.Person
[예제2]
StringTest.java
package classex;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class StringTest {
public static void main(String[] args) throws ClassNotFoundException {
Class strClass = Class.forName("java.lang.String");
Constructor[] cons = strClass.getConstructors();
for(Constructor c : cons) {
System.out.println(c); // String 클래스의 Constructor 정보들을 알 수 있다.
}
System.out.println("======================");
Field[] fields = strClass.getFields();
for(Field f : fields) {
System.out.println(f);
}
System.out.println("======================");
Method[] methods = strClass.getMethods();
for(Method m : methods) {
System.out.println(m);
}
}
}
실행 결과
public java.lang.String(java.lang.StringBuffer)
public java.lang.String(java.lang.StringBuilder)
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],int,int)
public java.lang.String(byte[])
public java.lang.String(char[],int,int)
public java.lang.String(char[])
public java.lang.String(java.lang.String)
public java.lang.String()
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int)
public java.lang.String(byte[],int,int,int)
public java.lang.String(int[],int,int)
===============
public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER
===============
public boolean java.lang.String.equals(java.lang.Object)
public int java.lang.String.length()
public java.lang.String java.lang.String.toString()
public int java.lang.String.hashCode()
public void java.lang.String.getChars(int,int,char[],int)
public int java.lang.String.compareTo(java.lang.String)
public int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(java.lang.String)
public int java.lang.String.indexOf(java.lang.String,int)
public int java.lang.String.indexOf(int,int)
public static java.lang.String java.lang.String.valueOf(int)
public static java.lang.String java.lang.String.valueOf(char[])
public static java.lang.String java.lang.String.valueOf(java.lang.Object)
public static java.lang.String java.lang.String.valueOf(boolean)
public static java.lang.String java.lang.String.valueOf(char[],int,int)
public static java.lang.String java.lang.String.valueOf(char)
public static java.lang.String java.lang.String.valueOf(double)
public static java.lang.String java.lang.String.valueOf(float)
public static java.lang.String java.lang.String.valueOf(long)
public char java.lang.String.charAt(int)
public int java.lang.String.codePointAt(int)
public int java.lang.String.codePointBefore(int)
public int java.lang.String.codePointCount(int,int)
public int java.lang.String.offsetByCodePoints(int,int)
public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
public void java.lang.String.getBytes(int,int,byte[],int)
public byte[] java.lang.String.getBytes()
public boolean java.lang.String.contentEquals(java.lang.CharSequence)
public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
public boolean java.lang.String.startsWith(java.lang.String,int)
public boolean java.lang.String.startsWith(java.lang.String)
public int java.lang.String.lastIndexOf(java.lang.String)
public int java.lang.String.lastIndexOf(java.lang.String,int)
public int java.lang.String.lastIndexOf(int,int)
public int java.lang.String.lastIndexOf(int)
public java.lang.String java.lang.String.substring(int,int)
public java.lang.String java.lang.String.substring(int)
public boolean java.lang.String.isEmpty()
public java.lang.String java.lang.String.replace(char,char)
public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
public boolean java.lang.String.matches(java.lang.String)
public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String,int)
public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.CharSequence[])
public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.Iterable)
public java.lang.String java.lang.String.toLowerCase()
public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
public java.lang.String java.lang.String.toUpperCase()
public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
public java.lang.String java.lang.String.trim()
public java.lang.String java.lang.String.strip()
public java.lang.String java.lang.String.stripLeading()
public java.lang.String java.lang.String.stripTrailing()
public java.util.stream.Stream java.lang.String.lines()
public java.lang.String java.lang.String.repeat(int)
public boolean java.lang.String.isBlank()
public char[] java.lang.String.toCharArray()
public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
public java.lang.Object java.lang.String.resolveConstantDesc(java.lang.invoke.MethodHandles$Lookup) throws java.lang.ReflectiveOperationException
public java.lang.String java.lang.String.resolveConstantDesc(java.lang.invoke.MethodHandles$Lookup)
public java.util.stream.IntStream java.lang.String.codePoints()
public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
public int java.lang.String.compareToIgnoreCase(java.lang.String)
public boolean java.lang.String.endsWith(java.lang.String)
public java.lang.CharSequence java.lang.String.subSequence(int,int)
public java.lang.String java.lang.String.concat(java.lang.String)
public boolean java.lang.String.contains(java.lang.CharSequence)
public java.lang.String java.lang.String.indent(int)
public java.lang.String java.lang.String.stripIndent()
public java.lang.String java.lang.String.translateEscapes()
public java.util.stream.IntStream java.lang.String.chars()
public java.lang.Object java.lang.String.transform(java.util.function.Function)
public java.lang.String java.lang.String.formatted(java.lang.Object[])
public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
public static java.lang.String java.lang.String.copyValueOf(char[])
public native java.lang.String java.lang.String.intern()
public java.util.Optional java.lang.String.describeConstable()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()