equals(Object obj) 메서드
==의 경우 두 객체의 참조변수 값의 같고 다름을 판단하기 때문에 해당 기호는 주소값의 비교이다.
Object의 equasl()메소드도 참조 변수의 값으로 판단을 하는데 이것을 객체의 값 비교로 사용하기 위해서는 적절한 오버라이딩이 필요하다.
객체에 저장된 값을 비교하기 위해서는 equals 메서드를 오버라이딩 하여 사용하는데 해당 메서드를 값비교를 위해 오버라이딩한 예제이다.
String 클래스에 저장된 문자열 비교시에도 ==이 아닌 equals 메소드를 사용한다.
생성된 객체들은 모두 주소가 다르기 때문에 ==에서 다른 값이라고 인식되고, 오버라이딩 된 equals를 통해 객체의 주소 값이 아닌 객체의 값을 비교했을 때 같은 값을 가지고 있기 때문에 같은사람이라는 출력이나온다.
HashCode() 메서드
Object클래스의 hashCode메서드는 객체의 주소값으로 해쉬값을 만들기 때문에 객체마다 다른 해쉬값을 가진다.
(System.identityHashCode()와 Object클래스의 hashCode는 같은 방식으로 동작한다.)
인스턴스 값에대한 hashcode를 생성하여 같은 값은 같은 hash값을 갖기 위해서는 hashcode 메서드를 오버라이딩 하여 사용 해야한다.
String 클래스의 경우 String객체가 가진 문자열 값을 기반으로 HashCode를 생성하도록 오버라이딩 되어있으므로 위의 예제는 같은 HashCode를 출력한다. 그러나 Object의 hashcode원리와 같이 주소값을 기반으로 hashCode를 생성할 경우 두개의 객체는 다른 값을 출력한다.
또한 equals()를 오버라이딩 하는 상황이라면 hashCodoe()메서드도 적절하게 오버라이딩 해주어야 한다. 같은 객체라면 HashCode()메서드의 결과값도 같아야 하기 때문이다.
toString() 메서드
Object 클래스에 정의된 toString()
Object클래스에 정의된 toString()메서드의 경우 클래스이름@주소기반16진수hashcode문자열이 반환된다.
하지만 위의 정보들은 사용시 유용하지 않기 때문에 toString()메서드는 일반적으로 인스턴스 클래스에 대한 정보나 인스턴스 변수들의 값을 문자열로 반환하도록 오버라이딩하여 사용된다.
클래스에서 toString()메서드를 오버라이딩 한경우
위와같이 인스턴스 객체의 인스턴스 변수들을 출력하게 오버라이딩 후 출력하였다. Object클래스의 toString()메서드가 public 메서드이기 때문에 오버라이딩의 경우도 public으로 해주어야 한다.
clone() 메서드
clone() 메서드는 자신을 복제하여 새로운 객체를 생성하는 메서드이다.
Object클래스에 정의된 clone()은 단순히 인스턴스변수의 값만 복사하기 때문에 참조타입의 인스턴스 변수가 있는 클래스는 완전한 인스턴스 복제가 이루어지지 않는다.
clone()을 사용하려면, 먼저 clone메서드를 사용할 클래스가 Cloneable인터페이스를 구현해주어야한다.
Cloneable인터페이스를 구현한 클래스의 인스턴스만 clone()메서드를 사용할 수 있는 이유는 인스턴스 데이터를 보호하기 위해서이다. 해당 클래스의 인스턴스만 복제를 허용한다.
또한 clone()메서드를 호출할때는 반드시 예외처리를 해주어야한다.
clone()메서드는 객체에 저장된 값을 그대로 복제하지만, 객체가 참조하고있는 객체까지 복제하지 못한다. 객체가 참조하고있는 주소만을 복제할 뿐이다. 이러한 복제는 해당 객체의 주소를 복제하고 객체자체를 복제하는 것이 아니기 때문에 완전한 복제라고 보기어렵다. 객체의 주소가아닌 참조객체까지 복제하는 '깊은 복제(deep copy)'를 하기 위해서는 clone()메서드를 이용해서 적절하게 구현 해주어야한다.
shallow copy는 객체에 저장된 값을 그대로 복제하는 얕은복사이다. 참조변수 멤버가 있을경우 참조변수의 참조값 즉 주소값만 복제가된다.
deepcopy메서드의 경우 해당 참조변수 멤버의 객체값을 복사한다.
얕은 복사를 진행한 c2의 경우 원본인 c1의 값이 바뀔경우 c2의 값도 변경된다.
그러나 깊은 복사를 진행한 c3의 경우 c1이 변경되더라도 원본의 값을 유지한다.
깊은 복사를 통해 원본이 참조하고있는 Point객체까지 복제했기 때문에 위와같은 결과가 나타난다.
인스턴스 변수에 참조형 변수가 없는경우 clone()메서드만으로 충분하다.
그러나 위처럼 깊은복사를 clone메소드를 통해 구현하고싶다면 참조변수의 객체를 복제가 가능하도록 깊은복사 메서드를 구현 해주어야한다.
getClass() 메서드
getClass()메서드는 자신이 속한 클래스의 Class 객체를 반환하는 메서드이다. Class 객체는 이름이 'Class'인 클래스 객체이다.
Class객체는 클래스의 모든 정보를 담고 있으며, 클래스 당 1개만 존재한다. 클래스 파일이 '클래스 로더(ClassLoader)'에 의해 메모리에 올라갈 때, 자동으로 생성된다. 클래스 로더는 실행시에 클래스를 동적으로 메모리에 로드하는 역할을 한다.
getClass()메서드는 파일형태로 저장되어 있는 클래스를 읽어서 Class클래스에 정의된 형식으로 변환하는 것이다.
Class 객체에 대한 참조를 얻는 방법으로 클래스명.class.newInstance()를 사용했다.
해당 Class객체를 통해 해당 객체의 클래스 이름을 얻을 수 있다.
Class객체가 실무에서 자주 쓰일지는 잘모르겠다. 뭔가 난해하고 유용한가에 대한 의문이 생긴다.
'Programming > JAVA' 카테고리의 다른 글
StringBuffer클래스와 StringBuilder클래스 (0) | 2021.07.26 |
---|---|
String 클래스 (0) | 2021.07.26 |
예외처리 Exception handling (0) | 2021.07.17 |
Interface를 이용한 다형성 (0) | 2021.07.17 |
JAVA 접근 제어자 (0) | 2021.07.15 |