String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2);//true
String str3 = new String("hello");
String str4 = new String("hello");
String str5 = str4;
System.out.println(str3 == str4);//false
System.out.println(str4 == str5);//true

== 연산자

== 연산자는 피연산자가 원시타입일 때는 값이 같은지 비교하고 피연산자가 그외 객체일때는 주소가 같은지 검사한다.

* 참고로 primitive 타입이 == 비교를 통해 값 비교가 가능한 이유는 아래와 같다.

변수 선언부는 Java Runtime Data Area의 Stack 영역에 저장이 되고, 
해당 변수에 저장된 상수는 Runtime Constant Pool에 저장되어있다. 
Stack의 변수 선언부는 해당 Runtime Contant Pool의 주소값을 가지게 되고, 
만약 다른 변수도 같은 상수를 저장하고 있다면, 
이 다른 변수도 같은 Runtime Contant Pool의 주소값을 가지게 때문에 엄밀히 말하면 
primitive type 역시 주소값 비교가 되는 것이다.

equals()

equals는 내용이 같은지를 검사하는 메소드이다. 원시형은 내용이 같은지를 검사하고 referenceType은 객체의 주소가 같은지 검사한다. 다만 ==연산자와 다른점은 완전히 같은 객체를 가리키지 않아도 개발자가 true로 만들 수 있다는 것이다. 오버라이딩을 통해서!

hashCode()

hashCode()는 객체의 주소 해시값을 리턴한다.

Set<Person> hset = new HashSet<>();
Person person1 = new Person("jdk", 27);
Person person2 = new Person("jdk", 27);
System.out.println("person1 : "+person1.hashCode());//2018699554
System.out.println("person2 : "+person2.hashCode());//1311053135
System.out.println(person1.equals(person2));//true
hset.add(person1);
hset.add(person2);
System.out.println(hset.size());//2

person1과 person2의 해시코드가 다른것을 위 hashCode()메서드를 통해 확인할 수 있다. 이때문에 Set에 넣어도 두 객체는 다른것으로 이해된다.

때문에 equals와 hashCode는 반드시 함께 재정의 하여야한다.

원칙은 이렇다

  1. equals로 같은 객체라면 반드시 hashCode도 같은 값이어야 한다.
  2. hashCode값이 같더라도 equals로는 같지 않을 수 있다.

Untitled

정리