[JAVA] ==와 equals의 차이
== 연산자
== 연산자는 int, boollean과 같은 primitive type에 대해서는 값을 비교한다. reference type 에 대해서는 주소값을 비교한다. 사실 primitive type도 Constant Pool에 있는 특정 상수를 참조하는 것이기 때문에 결국 주소값을 비교하는것으로 볼 수 있다. 같은 상수를 참조하면 주소값이 같으니 결국 같은 값이면 동일하다고 판단할 수 있다.
equals()
equals()는 최상위 클래스인 Object에 포함되어 있기 때문에 모든 하위 클래스에서 재정의해서 사용이 가능하다.
public boolean equals(Object obj) {
return (this == obj);
}
equals()도 내부적으로는 == 연산자를 사용해 주소를 비교하는것과 다름이 없다. 하지만 String에서 사용하던 equals()는 내용이 주소를 비교하는 것이 아닌 내용을 비교하는 것이였다. 그럼 String클래스의 equals()를 봐보자.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
먼저 equals() 변수로 들어온 객체가 자기 자신과 주소값으 같으면 if (this == anObject) (이부분) true를 리턴한다. 주소 값이 다르다면 String 객체의 문자열을 Char 타입으로 하나씩 비교해보면서 끝까지 같다면 true를 리턴하고, 다르다면 false를 리턴한다.
String클래스에서는 equals()가 문자열을 비교하게 재정의 되어 만들어져있기 때문에 문자열비교가 가능했던것이다.
//reference type
String text1 = "sample";
String text2 = text1;
String text3 = new String("sample");
String text4 = new String("sample");
System.out.println(text1 == text2); //true
System.out.println(text1.equals(text2)); //true
System.out.println(text3 == text4); //false
System.out.println(text3.equals(text4)); //true
참고로 text1은 new 연산자가 아닌 = "" 로 만들었기 때문에 힙 영역안에 String Constant Pool에 (주소,값) 형태로 저장되어 진다. 그 이후 ""로 생성한 String객체는 먼저 String Constant Pool 안에 자신이 생성할 문자열과 같은 값이 존재하는지 찾아본다. 같은 값이 존재한다면 공간을 새로 만드는 것이 아니라 주소값을 미리 만들어진 String Constant Pool에 있는 값에 연결한다. 결국 같은 값을 가르키게 때문에 == 연산 , equals() 연산 둘다 true를 리턴하게 될 것이다.
가장 중요한 포인트는 ==는 주소값이 같은지 아닌지 비교하는 것이고, equals()연산도 내부적으로 주소값을 비교하지만 String클래스에서는 equals()를 재정의해 내용을 비교하게 되어있다.