JAVA에서 String 비교는 어떻게하나요?
자바에서 string비교는 어떻게 하나요?
저는 지금까지 string을 비교할 때 == 연산자를 사용해왔습니다.
근데 계속 사용하다보니 bug가 발생하는 상황이 자주있었고, 일부분을 .equals()로 변경한 후에 bug를 해결했습니다. 연산자가 문제인건가요? 연산자는 언제 사용해야만하고 언제 사용하면 안되는 거죠? ==와 .equals의 차이점이 뭔가요?
String은 참조형입니다. == 연산자는 그 문자열의 주소를 비교하고, .equals 메서드는 그 값을 비교합니다.
if("abc" == "abc") System.out.println("참"); if("abc" == "!abc".substring(1)) System.out.println("거짓");여기서 "abc" == "abc"라는 식은 참입니다.
그런데 "!abc".substring(1)은 "abc"가 맞는데, 왜 "abc" == "!abc".substring(1)라는 식은 거짓일까요?
참조형의 개념을 모른다면 이렇게 생각할 수 있습니다.
참조형에 대해 이해를 하고 있다면, 반대로 생각해야 합니다. "abc" == "abc"가 왜 참이지???
결론부터 말하자면, "abc"는 문자열 상수 리터럴로 컴파일 시점에 계산되며, 컴파일 시점에 값을 알 수 있습니다.
자바 컴파일러가 (컴파일 시점에 값이 같다는 걸 미리 알고) 최적화를 통해 같은 String 변수를 재사용합니다.
그러니까, 사실 "abc" == "abc"에서 두 "abc"는 자기 자신이라는 말이죠. (a == a)와 비슷합니다.
다른 객체에 값만 같은 게 아니라 주소까지 완전히 같은, 자기 자신이기 때문에 == 연산으로도 문제가 없던 것입니다.
하지만 "!abc".substring(1)의 경우에는 사정이 좀 다릅니다.
"!abc".substring(1)는 실행할 때 계산됩니다. "abc"의 값을 가진 String객체가 새로 생깁니다.
값은 같지만, 방금 새로 생긴, 다른 객체라는 말이죠. 그래서 주소도 다르고요.
그래서 주소만 비교하는 == 연산자로는 안 되고, .equals 메소드를 써야 하는 것입니다.
그러면 컴파일 타임에 계산될, 문자열 상수 리터럴끼리는 ==으로 비교해도 되냐?
글쎄요... 그 때는 굳이 문자열 안 쓰고, enum을 쓰는 게 더 좋을 것 같네요