- 자바에서 클래스를 선언할 때 extends로 다른 클래스를 상속하지 않으면
java.lang.Object 클래스를 상속한다. 즉 자바의 모든 클래스는 Object클래스의 자식클래스가 되므로
Object는 자바의 최상위 부모 클래스에 해당된다.
- Object 클래스는 필드가 없고 메소드로 구성되어있다. 이 메소드들은 모든 클래스들이 Object클래스를
상속하므로, 모든 클래스에서 이용할 수 있다.
package day04;
public class ObjectTest1 {
public static void main(String[] args) {
String data1 = "ABC";
String data2 = "ABC";
String data3 = new String("ABC");
String data4 = new String("ABC");
//System.out.println(3 == 3);//RAM에는 항상 상수를 담아놓는 constant pool이라는 공간이 존재한다.
System.out.println(data1 == data2);
System.out.println(data3 == data4);
System.out.println(data3.equals(data4));
System.out.println(data3.intern() == data4.intern());
//intern() : 해당 필드에 있는 문자열 값을 가져와준다.
}
}
equals - 객체 비교
- equals()메소드는 비교 연산자인 "=="과 동일한 결과가 리턴된다.
매개 타입 | Object로 모든 객체가 매개 값으로 대입될 수 있다. (Object가 최상위 타입이므로 모든 객체는 Object 타입으로 자동 타입 변환 될 수 있기 때문) |
리턴 타입 | boolean 두 객체가 동일한 객체라면 true, 그렇지 않으면 false를 리턴한다. |
1. Object equals()
- 객치의 주소를 비교한다. 즉 같은 값을 가진 객체라 할지라도 따로 생성되면 false이다.
public class Main {
public static void main(String args[]){
Name nameA = new Name("Aiden");
Name nameB = new Name("Aiden");
NAme nameC = nameA;
System.out.println(nameA.equals(nameB)); //False
System.out.println(nameA.equals(nameC)); //True
}
public static class Name {
private String name;
public Name(String name) {
this.name = name;
}
}
}
nameA 와 nameB 는 "Aiden"이라는 같은 이름의 값을 가진 객체이지만 해당 객체가 생성된 주소가 다르기 때문에
False를 리턴한다. 반면 nameC는 nameA를 할당했기 때문에 같은 주소이므로 True를 리턴한다.
2. String equals()
String 객체에 equlas를 쓸 때는 주소가 분명 다름에도 불구하고 문자열 값이 같으면 True를 리턴한 경우를
자주 볼 수 있다. 흔히 Java에서 문자열을 비교할 때는 equals 함수를 사용한다.
String 개게에서 equals가 주소가 다름에도 문자열만 같으면 True를 리턴하는 것은 String 객체에서는
Overriding된 equals 함수를 사용하기 때문이다.
String Class에서 equals 함수 사용 예제
public boolean equals(Object anObject){
if(this == anObject){
return true;
}
if(anObject instanceof String){
String anotherString = (String) anObject;
int n = alue.length;
if(n == anotherString.value.length){
char V1[] = value;
char v2[] = anotherString.value;
int i = 0;
while ( n-- != 0){
if(V1[1] != V2[i])
return false;
i++
}
return true;
}
}
return false;
}
package day04;
public class ObjExample {
public static void main(String[] args) {
ObjectTest4 exam1 = new ObjectTest4("blue");
ObjectTest4 exam2 = new ObjectTest4("blue");
ObjectTest4 exam3 = new ObjectTest4("red");
if(exam1.equals(exam2)) {
System.out.println("exam1과 exam2는 같다");
}else {
System.out.println("exam1과 exam2는 같지않다.");
}
if(exam1.equals(exam3)) {
System.out.println("exam1과 exam3는 같다 ");
}else {
System.out.println("exam1과 exam3는 같지않다.");
}
}
}
HashCode() - 객체 해시 코드
- 객체 해시 코드란 각 객체가 갖는 유일한 값(Code)를 의미한다.
- Object의 hashCode()는 원래 주소값에 의한 hashCode()로 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴 하기 때문에 객체마다 다른 값을 가지고 있다.
- HashMap은 우선 hashCode() 메소드를 실행해서 리턴된 해시코드 값이 같은지 검사하고 해시코드 값이 다르면
다른 객체로 판단, 같으면 equals() 메소드로 다시 검사한다. 따라서 hashCode() 메소드가 true가 나와도
equals()의 리턴 값이 다르면 다른 객체가 된다.
package day04;
public class Key {
public int number;
public Key(int number) {
this.number = number;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key)obj;
if(this.number == compareKey.number) {
return true;
}
}
return false;
}
@Override
public int hashCode() { //hashCode 재정의
return id.hashCode;
}
}
- hashCode를 재정의 하지 않으면 new Key(1)객체로 "홍길동"을 저장하고 다시 "new Key(1)" 객체로 저장된 "홍길동"을 읽으려고 시도했을 때 null이 출력된다.
- "홍길동"을 읽기 위해서는 재정의한 hashCode()메소드를 Key 클래스에 추가한다.
package day04;
import java.util.HashMap;
public class KeyExample {
public static void main(String[] args) {
HashMap<Key, String> hashMap = new HashMap<Key, String>();
hashMap.put(new Key(1), "홍길동");
String value = hashMap.get(new Key(1));
System.out.println(value);
}
}
- 저장할 때의 new Key(1)과 읽을 때 new Key(1)은 사실 다른 객체지만 HashMap은 hashCode()의 리턴값이 같고, equals()의 리턴값이 true가 나오기 때문에 동등 객체로 평가한다. 즉, 같은 식별키로 인식한다.
- 그래서 객체의 동등 비교를 위해서는 Object의 equals()메소드만 재정의하지 않고 hashCode() 메소드도 재정의해서논리적 동등 객체일 경우 동일한 해시코드가 리턴되도록 해야한다.
'JAVA > JAVA2' 카테고리의 다른 글
[java2] #13 - Wrapper Class (래퍼 클래스) (0) | 2022.07.19 |
---|---|
[java2] #12 - 빠른(향상된) for문 (0) | 2022.07.19 |
[java2] #10 - Generic(제네릭) (0) | 2022.07.16 |
[java2] #09 - Exception(예외)종류와 처리 (0) | 2022.07.14 |
[java2] #08 - GUI, awt 컨테이너와 컴포넌트 (0) | 2022.07.14 |