Integer 값을 비교할 때 'equals' 메서드를 사용하지 않고 '==' 연산자를 사용해 코드를 작성한 경우, 일부 값은 정확하게 비교가 되는 반면 일부 값에 대해서는 같은 값임에도 false를 반환하는 경우가 있었다.
e.g. 일부 값 (-128~127)에 대해서는 '==' 연산자로 비교 가능하고, 일부 값에서는 가능하지 않음
public static void main(String[] args) {
Integer a = 10;
Integer b = 10;
System.out.println(a==b); //true
System.out.println(a.equals(b)); //true
Integer x = 128;
Integer y = 128;
System.out.println(x==y); //false
System.out.println(x.equals(y)); //true
}
* 들어가기에 앞서 '==' 연산자는 참조, 즉 객체의 주소 값을 비교하고 'equals' 메서드는 객체의 값(데이터)를 비교한다는 사실을 짚어둔다.
그렇다면 위 코드의 경우 Wrapper 타입인 Integer 객체에 '==' 연산자를 사용하는 경우 모두 false 값이 반환되고, 'equals' 메서드를 사용하는 경우에만 true 값을 반환하는 것이 논리적으로 보인다. 하지만 위 코드의 경우 '10'의 경우에는 '==' 연산자로도 true 값이 반환된다.
왜 그런 일이 발생했는지, Java의 내부적인 동작 방식을 알아보자.
Integer Cache
ref.
In Java 5, a new feature was introduced to save the memory and improve performance for Integer type objects handling. Integer objects are cached internally and reused via the same referenced objects.
- This is applicable for Integer values in the range between –128 to +127.
- This Integer caching works only on auto-boxing.
- Integer objects will not be cached when they are built using the constructor.
즉, 설명에 따르면 Integer 객체는 내부적으로 cache되고, 참조 객체를 통해 재사용된다는 것을 알 수 있다.
또한,
적용 범위는 -128에서 127,
autoboxing, 즉 원시 타입(primitive type)에서 참조 타입(reference type)으로의 변환에서만 작동하며,
생성자를 통한 선언에서는 cache 되지 않는다.
e.g. 생성자를 통한 Integer 객체 생성 시 -128~127 사이의 값임에도 '==' 연산자로 비교되지 않음
public static void main(String[] args) {
Integer i = 100;
Integer j = new Integer(100);
Integer k = 100;
System.out.println(i==j); //false
System.out.println(i==k); //true
}
결론
Integer 객체에 할당할 값이 -128~127 사이로 고정적인 범위를 갖는 경우 '==' 연산자로 무리 없이 값 비교가 가능하다. 하지만, 내부 로직의 변화나 추후 허용 값의 범위가 변경될 경우를 고려해 'equals' 메서드를 사용하는 것이 안전하다.
ref.
'p-languages > java' 카테고리의 다른 글
java/ 배열을 요소로 갖는 리스트에서 배열의 값을 기준으로 오름차순 정렬하기 (0) | 2022.07.23 |
---|---|
java/ 8 또는 12 길이의 int 배열을 받아 전화번호 형식의 String으로 반환하기 (0) | 2022.06.06 |
java/ 내부 클래스의 종류와 내부 클래스를 사용함으로써 얻는 장점 (0) | 2022.05.23 |
java/ Stream 중간 처리 메서드 - filtering, mapping, sorting, looping (0) | 2022.05.23 |
java/ String.contains() : 문자열에 특정 부분 문자열이 있는지 확인하는 메서드 (0) | 2022.05.17 |