-
Object 클래스Computer Science/JAVA 2021. 8. 20. 22:38
Object 클래스는 모든 클래스의 최고 조상이기 때문에 Object 클래스의 멤버들은 모든 클래스에서 바로 사용 가능합니다.
equals(Object obj)
매개변수로 객체의 참조변수를 받아서 비교하여 그 결과를 boolean 값으로 알려주는 역할을 합니다.
public class EqualsEx1 { public static void main(String[] args) { Person p1 = new Person(1234); Person p2 = new Person(1234); System.out.println(p1 == p2); -> false System.out.println(p1.equals(p2)); -> true } } class Person { long id; Person(long id) { this.id = id; } @Override public boolean equals(Object o) { if(o instanceof Person) { return this.id == ((Person)o).id; } else { return false; } } }
equals를 오버라이딩해서 id값이 같다면 true를 리턴합니다.
하지만 ==는 참조변수의 주소를 비교하기 때문에 false를 리턴합니다.
hashCode()
이 메서드는 해싱 기법에 사용되는 해시함수를 구현한 것입니다. Object 클래스에 정의된 hashCode 메서드는 객체의 주소값을 이용해서 해시코드를 만들어 반환하기 때문에 서로 다른 두 객체는 같은 해시코드를 가질 수 없습니다. 클래스의인스턴스변수 값으로 객체의 같고 다름을 판단해야 하는 경우라면 equals 메서드 뿐 만 아니라 hashCode 메서드도 적절히 오버라이딩해야 합니다.
public class HashCodeEx1 { public static void main(String[] args) { var str1 = new String("abc"); var str2 = new String("abc"); System.out.println(str1 == str2); System.out.println(str1.equals(str2)); System.out.println(str1.hashCode()); System.out.println(str2.hashCode()); System.out.println(System.identityHashCode(str1)); System.out.println(System.identityHashCode(str2)); } }
clone()
이 메서드는 자신을 복제하여 새로운 인스턴스를 생성하는 일을 합니다. 어떤 인스턴스에 대해 작업을 할 때, 원래의 인스턴스는 보존하고 clone메서드를 이용해서 새로운 인스턴스를 생성하여 작업을 하면 작업이전의 값이 보존되므로 작업에 실패해서 원래의 상태로 되돌리거나 변경되기 전의 값을 참고하는데 도움이 됩니다.
Object 클래스에 정의된 clone()은 단순히 인스턴스변수의 값만을 복사하기 때문에 참조 타입의 인스턴스 변수가 있는 클래스는 완전한 인스턴스 복제가 이루어지지 않습니다.
public class CloneEx1 { public static void main(String[] args) throws CloneNotSupportedException { Point original = new Point(3, 5); Point copy = (Point)original.clone(); System.out.println(original); //(3, 5) System.out.println(copy); // (3, 5) System.out.println(original == copy); // 복사를 했기 때문에 false } } class Point implements Cloneable { int x, y; Point(int x, int y) { this.x = x; this.y = y; } @Override public String toString() { return "Point{" + "x=" + x + ", y=" + y + '}'; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
얕은 복사, 깊은 복사
clone()은 단순히 객체에 저장된 값을 그대로 복제할 뿐, 객체가 참조하고 있는 객체까지 복제하지는 않음.
객체 배열을 clone()으로 복제하는 경우는 원본과 복제본이 같은 객체를 고융하므로 완전한 복제라고 보기는 어려움. 이러한 복사를
얕은 복사
라고 함.반면 원본이 참조하고 있는 객체까지 복사하는 것을
깊은 복사
라고 하며, 깊은 복사에서는 원본과 복사본이 서로 다른 객체를 참조하기 때문에 원본의 변경이 복사본에 영향을 미치지 않음.public class ShallowDeepCopy { public static void main(String[] args) throws CloneNotSupportedException { Circle c1 = new Circle(new Point(1, 1), 2.0); Circle c2 = c1.shallowCopy(); Circle c3 = c1.deepCopy(); System.out.println("----------- 변경 전 -------------"); System.out.println(c1); System.out.println(c2); System.out.println(c3); c1.p.x = 3; c1.p.y = 3; System.out.println("----------- 변경 후 -------------"); System.out.println(c1); System.out.println(c2); System.out.println(c3); } } class Circle implements Cloneable { Point p; double r; public Circle(Point p, double r) { this.p = p; this.r = r; } // 얕은 복사 public Circle shallowCopy() { Object obj = null; try { obj = super.clone(); } catch(CloneNotSupportedException ignored) { } return (Circle) obj; } // 깊은 복사 public Circle deepCopy() throws CloneNotSupportedException { Circle c = (Circle) super.clone(); c.p = (Point)(c.p).clone(); return c; } @Override public String toString() { return "Circle{" + "p=" + p + ", r=" + r + '}'; } }
getClass()
이 메서드는 자신이 속한 클래스의 Class 객체를 반환하는 메서드인데, Class 객체는 이름이 'Class'인 클래스의 객체입니다.
Class 객체는 클래스의 모든 정보를 담고 있으며, 클래스 당 1개만 존재합니다. 그리고 클래스 파일이 '클래스 로더'에 의해서 메모리에 올라갈 때 자동으로 생성됩니다.
클래스 객체 얻기
Class 객체를 이용하면 클래스에 정의된 멤버의 이름이나 개수 등, 클래스에 대한 모든 정보를 얻을 수 있기 때문에 Class 객체를 통해서 객체를 생성하고 메서드를 호출하는 등 보다 동적인 코드를 작성할 수 있습니다.
public class ClassEx1 { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Card c = new Card("HEART", 3); // new 연산자로 객체 생성 Card c2 = Card.class.getDeclaredConstructor().newInstance(); // Class 객체를 통해서 객체 생성 Class<? extends Card> cObj = c.getClass(); System.out.println(c); System.out.println(c2); System.out.println(cObj.getName()); System.out.println(cObj.toGenericString()); System.out.println(cObj); } } final class Card { String kind; int num; Card() { this("SPADE", 1); } Card(String kind, int num) { this.kind = kind; this.num = num; } @Override public String toString() { return "Card{" + "kind='" + kind + '\'' + ", num=" + num + '}'; } }
'Computer Science > JAVA' 카테고리의 다른 글
Generics (0) 2021.08.20 String, StringBuilder, StringBuffer (0) 2021.08.20 예외 처리 (0) 2021.08.12 Maven vs Gradle (0) 2021.01.18 JVM 이해하기 (0) 2021.01.12