developer tip

Java 할당 연산자 실행

copycodes 2020. 10. 21. 08:13
반응형

Java 할당 연산자 실행


Java에서는 할당이 오른쪽 피연산자의 값으로 x == (y = x)평가 되므로 true.

그러나이 코드는 false.

public static void main(String[]args){
    String x = "hello";
    String y = "goodbye";
    System.out.println(x.equals(x = y));
}

왜 이런거야? 내 이해에 따르면 (x = y)먼저을 평가 x하여의 값 을 할당 한 다음 값 y을 반환합니다 y. 그런 다음 x.equals(y)해야하는 평가 true이후 xy지금 같은 참조를 공유해야하지만, 대신에, 내가 얻을 false.

소스와 출력이 "false"임을 보여주는 스크린 샷

여기서 무슨 일이 일어나고 있습니까?


우선, 이것은 흥미로운 질문입니다. 그러나 "실제 코드"에서는 절대로 나오지 말아야합니다. 동일한 줄에서 호출하는 변수에 할당하는 것은 작동 방식을 알고 있더라도 혼란 스럽기 때문입니다.

여기서 일어나는 일은 다음 3 단계입니다.

  1. 메서드를 호출 할 객체를 파악합니다 (즉, 첫 번째를 평가 x하면 문자열 "hello"에 대한 참조가 생성됨).
  2. 매개 변수를 파악합니다 (즉, 평가 하면 String "goodbye"를 가리 키도록 x = y변경 x되고 해당 String에 대한 참조도 반환 됨).
  3. equals# 2의 결과를 매개 변수로 사용하여 # 1의 결과에 대해 메서드 호출합니다 (각각 문자열 "hello"및 "goodbye"에 대한 참조가 됨).

해당 메서드에 대해 생성 된 바이트 코드를 보면 명확하게 알 수 있습니다 (Java 바이트 코드에 능통하다고 가정).

     0: ldc           #2                  // String hello
     2: astore_1
     3: ldc           #3                  // String goodbye
     5: astore_2
     6: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
     9: aload_1
    10: aload_2
    11: dup
    12: astore_1
    13: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
    16: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
    19: return

9 번 줄은 위의 1 단계입니다 (즉 x, 값을 평가 하고 기억합니다).

라인 # 10-12는 2 단계입니다.를로드 y하고 복제하여 (할당 식의 반환 값에 대해 한 번) x.

라인 # 13은 equals라인 # 9에서 계산 된 결과와 라인 # 10-12의 결과를 호출합니다 .


좋은 질문! 그리고 JLS에 답이 있습니다 ...

§15.12.4.1 (예 15.12.4.1-2). 메서드 호출 중 평가 순서 :

인스턴스 메서드 호출의 일부로 호출 할 개체를 나타내는식이 있습니다. 이 표현식은 메소드 호출에 대한 인수 표현식의 일부가 평가되기 전에 완전히 평가 된 것으로 보입니다.

그래서,

String x = "hello";
String y = "goodbye";
System.out.println(x.equals(x = y));

xbefore 발생이 .equals인수 expression 전에 먼저 평가 x = y됩니다.

Therefore,  a reference to the string  hello  is remembered as the target reference before the local variable x is changed to refer to the string goodbye. As a result, the equals method is invoked for target object hello with argument goodbye, so the result of the invocation is false.


It's important to remember that a String in java is an object, and therefore a reference. When you call

x.equals(...)

It is checking if the value at the location currently referenced by x is equal to what you are passing in. Inside, you are changing the value that x is referencing, but you are still calling equals with the original reference (the reference to "hello"). So, right now your code is comparing to see if "hello" is equal to "goodbye", which it clearly is not. After this point, if you use x again, it will result in a reference to the same value as y.


x=y in the parenthesis means that expression (x=y) is now goodbye, while the outer x in x.equals holds the value hello


Reimus gave the correct answer, but I'd like to elaborate.

In Java (and most languages) the convention is variable goes on the left, assignment on the right.

Let's Break it down:

String x = "hello";
//x <- "hello"

String y = "goodbye";
//y <- "goodbye";

For debugging purposes as well as code readability, it's always a good practice to split up your lines so that they only do one thing.

System.out.println(x.equals(x = y)); //Compound statement

Here, x.equals(...) is called on the original reference to x, or "hello", it is updated for the second reference.

I would write this as (and this will give you your expected answer):

x = y;
// x <- y = "goodbye"

boolean xEqualsX = x.equals(x);
// xEqualsX <- true

System.out.println(xEqualsX);
// "true"

Now this seems obvious that it should behave this way, but it's also really easy to see exactly what is going on in each line, which is something you should strive for.


I have tried your question in eclipse your both expression are correct. 1) x == (y = x) evaluate to true it is true because value of x assign to y which is 'hello' then x and y compare they will same so result will true

2) x.equal (x = y) y 값이 x에 할당되므로 x와 x는 값이 다르므로 결과가 거짓이므로 거짓입니다.


나는 평신도 용어로 질문을 "hello".equals("goodbye"). 그래서 그것은 거짓을 반환합니다.


Java에서 String은 클래스입니다.

String x = "hello";
String y = "goodbye"; 

동일하지 않은 두 개의 다른 값을 참조하고 비교하면 두 개의 다른 문자열입니다.

 System.out.println(x.equals(x = y)); 
//this compare value (hello and goodbye) return true

    System.out.println(x == (y = x)); 
// this compare reference of an object (x and y) return false  

x.equals (x를 y에 할당하고 항상 true를 반환)하는지 확인하므로 기본적으로 x.equals (true)

참고 URL : https://stackoverflow.com/questions/50970043/java-assignment-operator-execution

반응형