Java 16 공식 문서를 참고했습니다.
Java에서 모든 클래스는 Object를 상속받게 됩니다.
그러면 실제로 클래스 안에서 바로 사용할 수 있는 Object 메소드의 기능 중 hashCode, toString, equals 메소트를 예제 코드와 함께 알아봅니다.
Object의 해시 코드 값을 반환하는 함수입니다.
public class HelloWorld {
private int num = 3;
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
System.out.println(helloWorld.hashCode());
helloWorld.numChange(5);
System.out.println(helloWorld.hashCode());
}
public void numChange(int a) {
num = a;
}
}
918221580
918221580
HelloWorld 클래스의 인스턴스의 멤버 변수 수정에도 같은 해시 코드값을 가지기 때문에 객체 안의 값이 아닌 메모리 주소로 해시 코드를 만드는 것으로 유추할 수 있었습니다.
equals 메소드는 매개변수의 객체와 자신이 같은지 비교하는 함수입니다. 이 내용은 예제보다는 Object.java에 정의된 내용을 확인하면 바로 알 수 있습니다.
// Object.java
...
public boolean equals(Object obj) {
return (this == obj);
}
...
Object.java의 내부 코드에서 ==연산을 통해서 비교하므로 메모리 주소가 같은 객체를 비교하는 함수인 것을 알 수 있습니다.
객체를 문자열로 반환합니다. 재정의하지 않으면 "패키지이름.클래스이름@해시코드"로 문자열을 반환합니다.
public class HelloWorld {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
System.out.println(helloWorld.toString());
}
}
com.programmers.java.HelloWorld@36baf30c
현재 객체를 복사해서 복사한 내용의 새로운 객체를 생성합니다.
class A implements Cloneable{
private int num = 3;
private B b;
public void setNum(int n)
{
num = n;
}
public int getNum()
{
return num;
}
public void CreateB() {
b = new B();
}
public void setBData(String s)
{
b.setStr(s);
}
public String getBData()
{
return b.getStr();
}
public Object CloneObject() throws CloneNotSupportedException{
return super.clone();
}
}
class B{
private String str = "This is B!";
public void setStr(String s)
{
str = s;
}
public String getStr()
{
return str;
}
}
public class HelloWorld {
public static void main(String[] args) {
A a = new A();
a.CreateB();
System.out.println("초기 a 객체 값 : " + a.hashCode() + ", " + a.getNum() + ", " + a.getBData());
try {
A a2 = (A)a.CloneObject();
a.setNum(11);
a.setBData("This is origin!");
System.out.println("a 객체 원본 : " + a.hashCode() + ", " + a.getNum() + ", " + a.getBData());
System.out.println("a 객체 사본 : " + a2.hashCode() + ", " + a2.getNum() + ", " + a2.getBData());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
초기 a 객체 값 : 1554547125, 3, This is B!
a 객체 원본 : 1554547125, 11, This is origin!
a 객체 사본 : 1418481495, 3, This is origin!
primitive 값(int, float 등)은 원본, 사본 클래스가 수정에서 독립적인 값을 가지는 것을 확인할 수 있지만 Object 같은 객체의 멤버 변수의 경우에는 같은 주소를 가리키고 있기 때문에 원본 객체의 b 멤버 변수를 수정해도 사본까지 영향을 주는 것을 확인할 수 있습니다.
깊은 복사를 위해서는 clone을 재정의해야 하는 것을 알 수 있습니다.
현재 인스턴스의 런타임 클래스를 가져옵니다.
class A {
...
}
class B {
...
}
public class HelloWorld {
public static void main(String[] args) {
A a = new A();
B b = new B();
System.out.println(a.getClass());
System.out.println(b.getClass());
}
}
class com.programmers.java.A
class com.programmers.java.B
https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/Object.html