Java에서 int와 boolean과 같은 일반적인 데이터 타입의 비교는 ==이라는 연산자를 사용하여 비교한다.
하지만 String처럼 Class의 값을 비교할때는 == 대신
equals()라는 메소드를 사용해 비교하는데
어떨때 equals를 사용하고 어떨때 ==를 사용하는지,
equals와 == 은 어떤 차이점이 있는지 알아보자.
1. String 변수 생성시 주소할당
String변수를 생성할때는 두가지 방법이 있다.
1. 리터럴(literal)을 이용한 방식
2. new 연산자를 이용한 방식
위의 두 방식에는 큰 차이점이 있다.
리터럴을 사용하게 되면 string constant pool*이라는 영역에 존재하게 되고
new를 통해 String을 생성하면 Heap 영역에 존재하게 된다.
String str1 = "apple"; //리터럴 이용
String str2 = new String("banana"); //new 연산자를 이용
String을 리터럴로 선언할 경우,
내부적으로 String의 intern() 메서드가 호출되게 되고
intern() 메서드는 주어진 문자열이 string constant pool에 존재하는지 검색하고
있다면 그 주소값을 반환, 없다면 string constant pool에 넣고 새로운 주소값을 반환한다.
2. 주소값 비교(= =)와 값 비교(equals)
==연산자와 equals()메소드의 가장 큰 차이점.
== 연산자는 비교하고자 하는 두개의 대상의 주소값을 비교하는데,
String클래스의 equals 메소드는 비교하고자 하는 두개의 대상의 값 자체를 비교한다는 점이다.
equals()는 모든 객체의 부모 클래스인 Object에 정의되어있는 메소드다.
String 클래스는 위와 같이 equals()를 오버라이드하여 인자로 전달된 String의 문자열을 비교한다.
코드를 살짝 보면,
== 키워드로 객체가 갖다면 더 확인하지 않고 true를 리턴하고
객체가 다른 경우 인자가 String이라면 문자열을 비교하여 동일한지에 대한 결과를 리턴하고 있다.
기본 타입의 int, char형등은 Call by Value* 형태로
기본적으로 대상에 주소값을 가지지 않는 형태로 사용된다.
하지만 String은 일반적인 타입이 아니라 클래스다.
클래스는 기본적으로 Call by Reference 형태로 생성 시 주소값이 부여된다.
그렇기에 String타입을 선언했을때는 같은 값을 부여하더라도 서로간의 주소값이 다른 것이다.
* Call by value, Call by reference 차이
그럼 '==' 와 'equals' 를 하나씩 살펴보도록 하자.
3-1. 문자열 비교 ( = = )
== 로 문자열을 비교하지 않는 이유
public class compare {
public static void main(String[] args) {
String s1 = "apple";
String s2 = new String("apple");
if(s1 == s2) {
System.out.println("두개의 값이 같음.");
} else {
System.out.println("두개의 값이 같지 않음.");
}
}
}
위 코드를 실행해보면 '두개의 값이 같지 않음.'이 출력된다.
두개의 값이 서로 다르다는 결과가 나온 것이다.
==는 객체가 같은지를 비교하지만 객체가 갖고 있는 문자열을 비교하진 않기 때문이다.
== 연산자의 경우 참조 타입 변수들 간의 연산은 동일한 객체를 참조하는지,
다른 객체를 참조하는지 알아볼 때 사용된다.
참조 타입의 변수의 값은 힙 영역의 객체 주소이므로, 결국 주소 값을 비교하는 것이 되어 다르다는 결론이 나온 것이다.
그래서 자바에서 문자열을 비교하려면 equals라는 메서드를 활용하여 두개의 값을 비교해주어야 한다.
3-2.문자열 비교 equals ()
public class compare {
public static void main(String[] args) {
String s1 = "apple";
String s2 = new String("apple");
if(s1.equals(s2)) {
System.out.println("두개의 값이 같음.");
} else {
System.out.println("두개의 값이 같지 않음.");
}
}
}
String 클래스안에 있는 equals라는 메서드를 사용하면
두 비교대상의 주소 값이 아닌 데이터값을 비교하기 때문에
어떻게 String을 생성하느냐에 따라 결과가 달라지지 않고 정확한 비교를 할 수 있다.
4.문자열 비교 compareTo()
compareTo()은 두개의 문자열을 비교한다.
동일한지의 여부만 확인할 수 있는 equals()와 다르게 어떤 문자가 사전적인 순서로 앞에 있는지도 리턴해 준다.
따라서 compareTo()를 이용하면 리스트를 오름차순으로 정렬하거나 내림차순으로 정렬할 수 있다.
리턴 값은 0, 음수, 양수의 int가 리턴되며 의미는 다음과 같다.
- 0 : 두개의 문자열이 동일
- 양수 : compareTo()를 호출하는 객체가 인자보다 사전적으로 순서가 앞설 때
- 음수 : 인자가 객체보다 사전적으로 순서가 앞설 때
'☕️자바 𝗝𝗔𝗩𝗔' 카테고리의 다른 글
[IntelliJ] 'invalid source release: 17' 컴파일 에러 발생 이유 및 해결 (0) | 2022.07.11 |
---|---|
자바 JVM, JDE, JDK (JDK와 JRE의 차이점) (0) | 2022.05.30 |
[Java] 자바 String Pool과 new String (Java의 String은 어디에 저장되는가) (0) | 2022.05.19 |
Call by value, Call by reference 차이 (자바에서의 Call by value, Call by reference) (0) | 2022.05.19 |
[자료구조] 자바 Queue add, offer 메소드 차이 (0) | 2022.05.17 |
댓글