본문 바로가기
내일배움캠프/회고록

6월 18일 화요일

by jhdevtrace 2024. 6. 18.

오늘은 SQL 위주로 했다.

SQL은 예전에 공부했던 경험이 있어서, 기초 단계인 아직까지는 예전 기억을 떠올리며 괜찮게 잘 풀어나가고 있다. 

알고리즘 문제 하나를 풀다가, 문제를 마주했다.

 

오늘의 문제

나는 보통 == 연산자로 비교를 해왔다. 당연하게도 == 연산자는 서로의 값을 비교하는 것으로 알고 있었다. 근데 분명 값이 같은데도, 값이 틀리다는 결과가 나오게 됐다.

 

 

결론 :

== 연산자는 참조 주소가 같은지 확인하는 것.

기본 자료형(int, char, boolean, double)의 경우 실제 값을 직접 메모리에 저장하게 돼서, equals() 메서드와 동일한 결과가 나온다.

래퍼 클래스(Integer, Double, Character) 또는 객체를 비교하게 되면, 같은 값을 가지고 있는 객체라고 할지라도, 객체가 같은 메모리에 저장되어 있는 것이 아니기 때문에, 같다는 결과가 나올 수 없다.

equals() 메서드는 객체의 값이 동일한지 확인하는 것

 

 

본문

문자열 비교 방법에 대해 하나 배웠다.

나는 보통 비교 연산자인 ==를 엄청 자주 사용했다. 문자열 비교에서도 당연하게 쓰고 있었는데,

equals() 를 사용해야 하는 경우가 있다는 것을 알았다.

주어진 코드에서 문제가 발생하는 이유는 문자열 비교에 사용된 == 연산자와 String 객체의 비교 방법에 있습니다. 자바에서 문자열을 비교할 때는 == 연산자 대신 equals() 메서드를 사용해야 합니다.

(내가 사용했던 코드가 있었는데, 잃어버렸다. 간략히 설명하자면 사용자가 입력한 "Kim"과 내가 String 객체를 만들어서 값을 비교하려고 했다.)

 

문자열 비교에서는 == 연산자는 두 문자열의 참조를 비교하는 것이므로 예상과 다른 결과를 초래할 수 있습니다. 따라서 "Kim"과 같은 문자열을 비교할 때는 equals() 메서드를 사용하여야 합니다.

 

 

자바에서 == 연산자는 객체의 참조를 비교합니다. 즉, 두 개의 객체가 메모리 상에서 동일한 위치를 가리키고 있는지를 비교합니다. 반면에 equals() 메서드는 객체의 내용을 비교합니다.

문자열 리터럴이나 String 객체를 생성할 때, 자바는 문자열 풀(String Pool)이라는 특별한 메모리 영역에 문자열을 관리합니다. 따라서 같은 문자열 리터럴을 사용하면 같은 객체를 참조하게 됩니다. 하지만 동적으로 생성된 문자열 객체는 새로운 메모리 위치에 저장됩니다.

따라서 "Kim"이라는 문자열 리터럴은 하나의 객체를 참조하게 되어 == 연산자를 사용하여 비교할 경우 동일성(참조 값이 같은지)을 비교할 수 있습니다. 예를 들어:

java코드 복사
String a = "Kim";
String b = "Kim";

System.out.println(a == b); // true, 같은 문자열 리터럴을 참조하므로 동일한 객체를 가리킴
System.out.println(a.equals(b)); // true, 문자열의 내용이 같으므로 true

그러나 new String()을 사용하여 명시적으로 새로운 String 객체를 생성하면 다른 메모리 위치에 저장되기 때문에 == 연산자로 비교할 경우 false가 될 수 있습니다:

java코드 복사
String a = "Kim";
String c = new String("Kim");

System.out.println(a == c); // false, 다른 메모리 위치에 저장됨
System.out.println(a.equals(c)); // true, 문자열의 내용이 같으므로 true

따라서 일반적으로 문자열의 내용을 비교할 때는 equals() 메서드를 사용하는 것이 안전하고 올바른 방법입니다. 이는 객체의 내용을 비교하기 때문에 문자열 값이 같으면 true를 반환합니다.

 

 

예시)

public class Main {
    public static void main(String[] args) {
        // String 객체 생성
        String str1 = new String("hello");
        String str2 = new String("hello");

        // str1과 str2의 참조 주소 비교
        System.out.println(str1 == str2); // false

        // str1과 str2의 값 비교
        System.out.println(str1.equals(str2)); // true

        // 동일한 객체를 참조하는 경우
        String str3 = str1;
        System.out.println(str1 == str3); // true
    }
}

 

 

 

메모리 구조 시각화

String str1 = new String("hello");
String str2 = new String("hello");
String str3 = str1;

Heap Memory:
----------
|  "hello"  |  <--- str1, str3
----------
|  "hello"  |  <--- str2
----------

 

'내일배움캠프 > 회고록' 카테고리의 다른 글

6월 25일 화요일  (0) 2024.06.25
6월 21일 금요일  (0) 2024.06.21
6월 20일 목요일  (0) 2024.06.20
6월 19일 수요일  (0) 2024.06.19
6월 17일 월요일  (0) 2024.06.17