Java에서 "exit"라는 문자열을 입력받으면 진행 중인 반복문을 종료시키는 프로그램을 코딩하면서 자연스럽게 `==`연산자를 사용하여 "exit" 문자열을 입력받았는데도 반복문이 종료되지 않았던 경험이 있습니다.
이때 저는 `==`연산자와 `equals()`메서드의 차이를 알 수 있었던 좋은 경험이었습니다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); //Scanner 객체 생성
String exit ="";
while(!exit.equals("exit")){
System.out.println("종료하려면 exit를 입력해 주세요 :");
exit=sc.nextLine();
}
System.out.println("프로그램이 종료되었습니다.");
}
}
Java 에서 프로그램을 작성하다 보면 위 코드처럼 두 객체가 같은지 비교할 경우가 자주 있습니다. 기본 타입의 값을 비교할 때에는 `==`연산자를 사용하지만, 객체의 값을 비교할 때에는 `equals()`메서드를 사용하여야 합니다. 그 이유에 대해 이 글을 통해 정리해 보고자 합니다.
== 연산자
주로 숫자 데이터 타입의 값을 비교할때 자주 사용한 비교연산자 중의 하나인 `==`연산자는 두 객체의 내용물의 값이 같은지 비교하는 것이 아니라, 두 레퍼런스(참조형 변수)가 같은 객체를 가리키고 있는지 비교하는 연산자입니다. 즉, 참조하고 있는 주소가 같은지 비교하는 연산자 입니다.
public class Point {
//멤버 변수
int x;
int y;
//생성자
public Point(int x, int y){
this.x=x;
this.y=y;
}
}
public class Main {
public static void main(String[] args) {
//Point 객체 생성
Point a = new Point(2, 3);
Point b = new Point(2, 3);
Point c = a;
//false
if (a == b) {
System.out.println("a==b"); //출력 안됨
}
//true
if (a == c) {
System.out.println("a==c"); //a==c 출력됨
}
}
}
예제 코드를 통해 알 수 있듯이 `a`인스턴스의 주소값을 복사해서 가리키고 있는 인스턴스 `c`와 `a`가 같다고 출력되는 것을 볼 수 있습니다. 위 예제를 통해 `==`연산자는 동일한 주소를 가리키는지 비교하는 연산자임을 알 수 있습니다.
equals() 메서드
`equals()`메서드는 `==`연산자와 달리 객체의 값을 비교할 때 사용하는 메서드입니다. 그 이유는 두 객체의 내용을 비교하는 메서드 이기 때문입니다.
즉, 인자로 전달받은 값과 자기 자신을 비교하여 두 객체의 내용이 같은지 비교하여 반환해 줍니다.
public class Main {
public static void main(String[] args) {
String a = new String("Hello World!");
String b = new String("Hello World!");
//false
if(a==b){
System.out.println("a==b"); //주소값이 달라서 출력안됨
}
//true
if(a.equals(b)){
System.out.println("a와 b 내용은 Hello World!로 동일합니다!"); //내용이 같아서 출력됨
}
}
}
위의 간단한 코드 예제를 통해 알 수 있듯이 `a`와 `b`는 서로 객체를 가리켜 주소가 다릅니다. `a==b`로 비교하였을 때는 주소값이 다르기 때문에 출력이 되지 않지만, `a.equals(b)`로 비교하였을대는 내용값이 같기 때문에 출력되는 것을 볼 수 있습니다.
※ Object 클래스의 equals() & String 클래스의 equals()
자바의 모든 클래스의 최상위 부모 클래스인 Object 클래스의 equals(Object obj) 메서드는 전달 인자인 obj와 this(자기 자신)의 레퍼런스를 ==연산자로 단순 비교하여 결과를 리턴하도록 만들어져 있습니다(Object 클래스의 equals() 메서드는 ==연산자와 동일한 결과값을 리턴한다). 그렇기 때문에 원래 equals()메서드는 내용에 대해서 비교하지 않습니다.
이러한 equals() 메서드를 String 클래스에서 상속받아 오버라이딩(Overriding, 재정의) 하여 두 문자열의 내용이 같은지 비교하는 메서드로 사용되는 것입니다.
따라서, 객체의 내용이 같다는 의미가 클래스마다 다를 수 있기 때문에 클래스를 만들 때 equals() 메서드를 오버라이딩(Overriding, 재정의) 하는 것이 원칙입니다.
//Object 클래스의 equals()메서드
public class Main {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
boolean result = obj1.equals(obj2);
System.out.println(result); //서로 주소값이 다르기 때문에 false 출력됨
}
}
String 클래스가 아닌 개발자가 생성하는 클래스에서 equals() 메서드를 오버라이딩(Overriding, 재정의) 해서 사용해 보는 예제 코드를 다음과 같이 작성해 보았습니다.
public class Point {
//멤버 변수
int x;
int y;
//생성자
public Point(int x, int y) {
this.x = x;
this.y = y;
}
//equals() 메서드 Overriding(재정의)
public boolean equals(Object obj) {
Point p = (Point) obj; //객체 obj를 Point 타입으로 다운 캐스팅
if (x == p.x && y == p.y) {
return true;
} else {
return false;
}
}
}
public class Main {
public static void main(String[] args) {
//Point 객체 생성
Point a = new Point(2, 3);
Point b = new Point(2, 3);
Point c = new Point(3, 4);
//false
if (a == b) {
System.out.println("a==b"); //주소가 달라서 출력 안됨
}
//true
if (a.equals(b)) {
System.out.println("a와 b의 내용은 같습니다."); //내용값이 같아서 출력됨
}
//false
if (a.equals(c)) {
System.out.println("a와 c의 내용은 다릅니다.");//내용값이 달라서 출력안됨
}
}
}
위의 예제 코드를 통해 알 수 있듯이 개발하는 클래스 내에서 `equals()` 메서드를 오버라이딩(Overriding, 재정의) 하여 사용할 수 있습니다.
재정의를 통해 객체의 내용값이 같으면 `true`를 리턴하도록 하는 메서드로 사용할 수 있습니다.
참조형 변수(문자열)의 내용을 비교하려면 `==`연산자 대신 `equals()` 메서드를 사용하여야 하며, String 클래스의 문자열이 아닌 다른 클래스 객체를 비교할 때에는 해당 클래스에서 `equals()`메서드를 오버라이딩(Overriding, 재정의) 해주어야 합니다.
Reference
- 황기태, 김효수, 명품 Java Programming. 생능출판, 2019
- Tistory, "Java 자바[API]-Object클래스, Object 클래스의 메소드1", https://kephilab.tistory.com/92
2. Java 자바 [API] - Object 클래스, Object 클래스의 메소드 1
자바의 클래스를 선언할 때 extends 키워드로 다른 클래스를 상속하지 않으면 암시적으로 java.lang.Object 클래스를 상속하게 된다. 따라서 자바의 모든 클래스는 Object 클래스의 자식이거나 자손 클
kephilab.tistory.com
- Tistory, "[Java] 문자열(String) 비교 방법 ==, equals() 차이", https://milku.tistory.com/112
[Java] 문자열(String) 비교 방법 ==, equals() 차이
서비스에서 문자열을 비교하던 중 같은 값을 비교했는데 false가 나오는 상황이 발생했습니다. 원인을 찾아보니 == 연산자로 문자열을 비교했기 때문이었습니다. == 연산자는 객체의 주소를 비교
milku.tistory.com
'수수한 코딩세상 > Java' 카테고리의 다른 글
[Java] Project, Package, Class, Method, Variable, Constant 이름 짓는 규칙 (명명 규칙) (0) | 2024.08.02 |
---|---|
[Java] 호출 방식으로 알아보는 인스턴스 멤버 & 클래스 멤버 차이 (1) | 2024.07.31 |
[Java] 자바에서 입력 받는 방법 System.in & Scanner 클래스 (0) | 2024.07.26 |
[Java] 요리 레시피 노트패드로 알아보는 next(), nextLine() 차이점 (1) | 2024.07.24 |
[Java] 랜덤 닉네임 생성기 (1) | 2024.06.19 |