[java] Java에서 ==와 equals ()의 차이점은 무엇입니까?

나는 이것을 올바르게 이해하는지 분명히하고 싶었습니다.

  • == 참조 비교입니다. 즉, 두 객체가 모두 동일한 메모리 위치를 가리 킵니다.
  • .equals() 객체의 값 비교로 평가


답변

일반적으로 질문에 대한 대답은 “예”이지만 …

  • .equals(...) 비교 대상으로 작성된 내용 만 비교합니다.
  • 클래스가 equals 메서드를 재정의하지 않으면 기본적 equals(Object o)으로이 메서드를 재정의 한 가장 가까운 부모 클래스의 메서드가 사용됩니다.
  • 부모 클래스에서 재정의를 제공하지 않은 경우 기본적으로 부모 클래스 인 Object의 메서드가 기본 설정되므로 메서드가 그대로 유지됩니다 Object#equals(Object o). Object API에 따라 이것은 ==; 즉, 두 변수가 동일한 객체를 참조하고 참조가 하나이고 동일한 경우에만 true를 반환합니다 . 따라서 기능 평등이 아닌 객체 평등을 테스트합니다 .
  • “계약을 위반하지 않도록” 재정의하는 hashCode경우 항상 재정의 해야합니다 equals. API에 따라 hashCode()두 객체 의 메소드 에서 반환 된 결과는 메소드 가 동일한 것으로 표시되는 경우 동일 해야합니다equals . 대화가 반드시 사실 은 아닙니다 .

답변

String 클래스와 관련하여 :

equals () 메소드 는 두 객체 참조가 동일한 String 인스턴스를 참조하는지 여부에 관계없이 String 인스턴스 (힙의) 내 “값”을 비교합니다. String 유형의 두 객체 참조가 동일한 String 인스턴스를 참조하면 훌륭합니다! 두 객체 참조가 두 개의 다른 String 인스턴스를 참조하는 경우 차이가 없습니다. 비교되는 각 String 인스턴스 내의 “값”(즉, 문자 배열의 내용)입니다.

반면에 “==” 연산자두 객체 참조 의 값을 비교 하여 동일한 String 인스턴스 를 참조하는지 여부를 확인합니다 . 두 객체 참조의 값이 동일한 String 인스턴스를 “참조”하는 경우 부울 식의 결과는 “true”입니다 ..duh. 반면에 두 객체 참조의 값이 서로 다른 String 인스턴스 를 “참조”하는 경우 (두 String 인스턴스가 동일한 “값”을 갖더라도 (즉, 각 String 인스턴스의 문자 배열의 내용이 동일하더라도) 부울 식의 결과는 “false”입니다.

다른 설명과 마찬가지로 들어가게하십시오.

나는 이것이 약간의 문제를 해결하기를 바랍니다.


답변

“primitives”또는 “Object Types”에 대해 이야기하고 있는지에 따라 약간의 차이가 있습니다. “정적”또는 “비 정적”멤버에 대해 이야기하는 경우에도 마찬가지입니다. 위의 모든 내용을 혼합 할 수도 있습니다 …

다음은 예제입니다 (실행할 수 있음).

public final class MyEqualityTest
{
    public static void main( String args[] )
    {
        String s1 = new String( "Test" );
        String s2 = new String( "Test" );

        System.out.println( "\n1 - PRIMITIVES ");
        System.out.println( s1 == s2 ); // false
        System.out.println( s1.equals( s2 )); // true

        A a1 = new A();
        A a2 = new A();

        System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
        System.out.println( a1 == a2 ); // false
        System.out.println( a1.s == a2.s ); // true
        System.out.println( a1.s.equals( a2.s ) ); // true

        B b1 = new B();
        B b2 = new B();

        System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
        System.out.println( b1 == b2 ); // false
        System.out.println( b1.getS() == b2.getS() ); // false
        System.out.println( b1.getS().equals( b2.getS() ) ); // true
    }
}

final class A
{
    // static
    public static String s;
    A()
    {
        this.s = new String( "aTest" );
    }
}

final class B
{
    private String s;
    B()
    {
        this.s = new String( "aTest" );
    }

    public String getS()
    {
        return s;
    }

}

다음 링크를 통해 “==”(Equal Operator) 및 “.equals (…)”(java.lang.Object 클래스의 메소드)에 대한 설명을 비교할 수 있습니다.


답변

==와 equals의 차이점은 좀 더 자세히 살펴보기로 결정하기 전까지는 혼란 스러웠습니다. 그들 중 많은 사람들이 문자열을 비교하기 위해서는 사용 equals하지 말아야한다고 말합니다 ==. 이 대답에서 희망이 차이를 말할 수 있습니다.

이 질문에 대답하는 가장 좋은 방법은 몇 가지 질문을하는 것입니다. 시작하겠습니다 :

아래 프로그램의 출력은 무엇입니까?

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

당신이 말하는 경우,

false
true

나는 당신이 옳다고 말할 것이지만 왜 그렇게 말했 습니까? 그리고 출력이

true
false

나는 당신이 틀렸다고 말할 것입니다. 그러나 여전히 당신에게 물어볼 것입니다. 왜 당신이 옳다고 생각합니까?

좋아, 이것에 대답 해 보자.

아래 프로그램의 출력은 무엇입니까?

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

지금 말하면

false
true

나는 당신이 틀렸다고 말하지만 왜 지금은 틀린가 ? 이 프로그램의 올바른 출력은

true
false

위의 프로그램을 비교하고 생각하십시오.

확인. 이제 이것이 도움이 될 수 있습니다 (이 글을 읽으십시오 : 객체의 주소를 인쇄하십시오 -불가능하지만 여전히 사용할 수 있습니다).

String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);

System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));

날이 밖으로 인쇄 ideone 위해 (: 당신은 위의 코드에서 마지막 세 줄의 출력에 대해 생각하는 시도 할 수 있습니다 당신은 여기에 코드를 확인하실 수 있습니다 )

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

오! 이제 identityHashCode (mango)는 identityHashCode (mango2)와 같지만 identityHashCode (mango3)와 같지 않습니다.

모든 문자열 변수 (mango, mango2 및 mango3) 는 “mango”인 동일한 값을 갖지만 identityHashCode()여전히 모두 동일하지는 않습니다.

이제이 줄의 주석을 해제 // mango2 = "mang";하고 이번에 다시 실행하여 세 가지 identityHashCode()가 모두 다른 것을 볼 수 있습니다. 흠 그것은 유용한 힌트입니다

우리는 if hashcode(x)=Nand hashcode(y)=N=>x is equal to y

Java가 내부적으로 어떻게 작동하는지 잘 모르겠지만 이것이 내가 말했을 때 일어난 일이라고 가정합니다.

mango = "mango";

자바 "mango"mango다음과 같은 변수에 의해 지적 된 문자열 을 만들었습니다.

mango ----> "mango"

이제 내가 말했을 때 다음 줄에서 :

mango2 = "mango";

실제로 다음과 같은 문자열 "mango"을 재사용 했습니다.

mango ----> "mango" <---- mango2

망고와 망고 2 모두 같은 참조를 가리키고 있습니다.

mango3 = new String("mango")

실제로 “망고”에 대한 완전히 새로운 참조 (문자열)를 만들었습니다. 이런 식으로 보입니다

mango -----> "mango" <------ mango2

mango3 ------> "mango"

그래서 내가에 대한 값을 mango == mango2낼 때을 내 보냅니다 true. 에 대한 값을 mango3 == mango2넣을 때 false(값이 같더라도) 나타납니다.

그리고 주석을 해제 할 때 // mango2 = "mang";
실제로 “mang”라는 문자열을 생성하여 그래프를 다음과 같이 설정했습니다.

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

이것이 identityHashCode가 모두 동일하지 않은 이유입니다.

이것이 여러분에게 도움이되기를 바랍니다. 실제로 == 실패하고 equals ()가 통과하는 테스트 사례를 생성하고 싶었습니다. 내가 틀렸다면 의견을 말하고 알려주십시오.


답변

==의 두 변수 여부 운영자가 테스트는 (메모리 어드레스 포인터 일명) 동일한 참조 .

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (The objects are not the same)

bar = foo;

if(foo==bar)
// True (Now the objects are the same)

반면 등호 () 메소드 테스트 두 변수가있는 개체 참조 여부 동일한 상태 (값) .

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

건배 🙂


답변

사용자 정의 클래스와 함께 사용하려면 equals 함수를 재정의해야합니다 (다른 함수와 함께).

equals 메소드는 객체를 비교합니다.

==이진 연산자는 메모리 어드레스를 비교한다.


답변

.equals ()를 재정의하지 않으면 ==와 .equals ()는 동일한 객체를 참조합니다.

.equals ()를 재정의하면 원하는 작업을 수행 할 수 있습니다. 호출하는 객체의 상태를 전달 된 객체의 상태와 비교하거나 super.equals ()를 호출 할 수 있습니다.