-
[Java] String비교하기. equals와 ==의 차이? String pool이란?개발 끄적끄적/Java 2020. 6. 5. 02:54반응형
개발을 하다 보면 두 개의 문자열을 비교해야 할 때가 자주 있습니다.
두 개의 문자열을 비교할 때 어떻게 비교할지, 어떤 차이점이 있는지 알아보겠습니다.
먼저, Java가 내부적으로 String을 어떻게 처리하고 있는지 알아보겠습니다.
Java에서 String 객체의 값의 변경은 불가합니다.
String name = "Tony"; name += " Stark";
위와 같은 코드를 짠다면 실제로 "Tony" 값을 가지고 있던 name은 버리고 "Tony Stark"를 가지고 있는 name을 만드는 것입니다. 여기서 name의 실제 내용 "Tony"는 컴파일 후에 String pool에 들어갑니다.
두 개의 String 객체를 비교하는 것엔 두 가지 방법이 있습니다.
- == 연산
- equals() 메소드
1. == 연산
Java에서 String 객체 간의 값을 비교하는 것이 아니고 같은 메모리를 참조하고 있는지 여부를 판단한다는 것은 많이들 알고 계십니다.
그렇다면 아래의 코드는 실패할까요?
String human1 = "Tony"; String human2 = "Tony"; assertTrue(human1 == human2);
- 맨 처음 human1을 선언했을 때 "Tony"란 값이 String pool에 들어갑니다.
- human2를 만들려 보니 "Tony"란 값은 이미 String pool에 존재하기 때문에 String pool에 만들어주지 않고 기존에 만들어둔 값을 할당해줍니다.
- 위 코드는 성공합니다.
String human1 = "Tony"; String human2 = new String("Tony"); assertTrue(human1 == human2);
- human2를 선언할 때 String pool을 살펴보지 않고 새로운 객체를 생성하도록 했습니다.
- 따라서 위 코드는 실패합니다.
2. equals() 연산
위에서 사용했던 코드를 그대로 살펴보겠습니다.
String human1 = "Tony"; String human2 = "Tony"; assertTrue(human1.equals(human2));
String human1 = "Tony"; String human2 = new String("Tony"); assertTrue(human1.equals(human2));
위 코드는 둘 다 성공합니다.
String 객체끼리의 ==연산은 해당 객체가 참조하는 메모리를 비교하는 것이지만, equals는 값을 비교하는 것이기 때문에 선언 과정과 상관 없이 성공합니다.
그렇다면 문자열 비교는 무조건 equals() 메소드를 사용하면 되는 것인가?
꼭 그렇지는 않습니다.
잠깐 String 클래스의 intern()이라는 메소드에 대해 설명드리겠습니다.
String 클래스는 intern()이라는 메소드를 가지고 있으며 선언 시 기본적으로 호출하는 함수입니다.
이 메소드는 해당 literal (실제 내용 부분. 위 예제에선 "Tony")이 String pool에 있는지 확인 후 있으면 pool에 있는 literal을 가져오고 없으면 새로 등록합니다.
이 intern() 메소드의 특징을 활용하면 값 비교에 많은 연산을 필요로 할 때, 중복값이 많은 String을 처리할 때 더 효율적인 코딩을 할 수 있게 해줍니다.
==연산은 실제 값을 비교하는 equals() 보다 빠른 속도, 적은 메모리로 처리할 수 있기 때문입니다.
String human1 = "Tony"; String human2 = new String("Tony"); String human3 = human2.intern(); assertTrue(human1.equals(human2)); assertTrue(human1 == human3);
위의 코드가 모두 성공하는 것입니다.
'문자열 비교는 무조건 equals()다!' 라고 생각하기보다 왜 equals를 권장하는지, 이유에 대해 생각하고 상황에 맞게 사용하면 좋을 듯 합니다.
사실 실제로 intern() 메소드가 잘 쓰이지는 않습니다. 하지만 많은 양의 String 데이터를 관리하거나 파싱하는 작업이 필요한 앱에서는 사용하기를 재고해볼 수 있겠습니다.
반응형