튼튼발자 개발 성장기🏋️

값을 비교할 것인가 메모리 주소를 비교할 것인가? 본문

프로그래밍/JAVA

값을 비교할 것인가 메모리 주소를 비교할 것인가?

시뻘건 튼튼발자 2024. 8. 28. 23:37
반응형

java에서 비교하는 방법은 참조 비교(==)값 비교(equals()) 두 가지가 있다.

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

/*
 * 리터럴이 이전에 상수 풀에 저장된 적이 있다면, 새로운 객체를 생성하지 않고 이미 존재하는 객체의 참조를 할당한다.
 * 따라서 같은 메모리의 주소를 바라보고 있기 때문에 첫 번째 비교문은 참이다.
 */
System.out.println(str1 == str2); // true

// str1과 str2는 같은 값인 "str"이 할당되어 있기 때문에 참이다.
System.out.println(str1.equals(str2)); // true

/*
 * 리터럴이 상수 풀에 존재하더라도, 힙 메모리에 새로운 String 객체가 생성된다.
 * 즉 위 예제에서 str1과 str3는 서로 다른 메모리 주소를 참조한다.
 */
System.out.println(str1 == str3); // false

// str1과 str3는 같은 값인 "str"이 할당되어 있기 때문에 참이다.
System.out.println(str1.equals(str3)); // true

 

 

 

그렇다면 Double은 어떨까?

/*
 * 오토박싱(Auto-boxing)이 일어나 double 값 1.2를 Double 객체로 변환하므로
 * d1, d2는 서로 다른 Double 객체를 참조한다.
 */
Double d1 = 1.2;
Double d2 = 1.2;
System.out.println(d1 == d2); // (1)
System.out.println(d1.equals(d2)); // (2)

double d3 = 1.2;
double d4 = 1.2;
System.out.println(d3 == d4); // (3)

System.out.println(d1.equals(d3)); // (4)
System.out.println(d1 == d3); // (5)

Double d5 = 0.0;
Double d6 = -0.0;
System.out.println(d5.equals(d6)); // (6)

 

(1): d1과 d2는 서로 다른 Double 객체를 참조하므로 거짓이다.

(2): d1, d2는 1.2 값을 가지고 있으므로 참이다.

(3): double은 원시 타입이므로, 값 자체를 비교하게 되므로 참이다.

(4): 오토박싱에 의해 d3은 Double 객체로 변환된다. 그렇다고 하더라도 값이 1.2로 같으므로 참이다.

(5): d1이 언박싱되므로 원시 타입간의 비교이기 때문에 값 자체를 비교한다. 그래서 참이다.

(6): 0.0과 -0.0을 비교할 때는 서로 다르다고 간주한다.

 

Double에서의 equals() 메서드와 String에서의 equals() 메서드의 차이는 뭘까?

실제로 String class와 Double class를 한 번 보면 이해하기 쉽다. Double 클래스의 equals() 메서드는 주어진 객체(obj)가 Double인지 확인한 후, 그 값이 동일한지 비교한다.

String 클래스의 equals() 메서드는 전달된 객체(obj)가 String 타입인지 확인한 후, 두 문자열의 길이가 같은지, 그리고 각 문자가 동일한지 순차적으로 비교한다.

 

  • Double.equals()는 Double 객체의 숫자 값을 비교한다.
  • String.equals()는 String 객체의 문자열 내용을 비교한다.

 

  // String class
  public final class String implements Serializable, Comparable<String>, CharSequence, Constable, ConstantDesc {
  
  // ...
  
  public boolean equals(Object anObject) {
    if (this == anObject) {
      return true;
    } else {
      boolean var10000;
      if (anObject instanceof String) {
        String aString = (String)anObject;
        if ((!COMPACT_STRINGS || this.coder == aString.coder) && StringLatin1.equals(this.value, aString.value)) {
          var10000 = true;
          return var10000;
        }
      }

      var10000 = false;
      return var10000;
    }
  }
  
  // ...
  
}


// Double class
public final class Double extends Number implements Comparable<Double>, Constable, ConstantDesc {

  // ...
  
  public boolean equals(Object obj) {
    return obj instanceof Double && doubleToLongBits(((Double)obj).value) == doubleToLongBits(this.value);
  }
  
  // ...
  
}
반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

문자열을 생성할 때 어떻게 생성하나요?  (0) 2024.08.28
Error와 Exception의 차이를 아시나요?  (1) 2024.08.28
STREAM 활용  (0) 2022.08.23
Optional  (0) 2022.08.12
Stream  (0) 2022.07.25