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
이후 x
와 y
지금 같은 참조를 공유해야하지만, 대신에, 내가 얻을 false
.
여기서 무슨 일이 일어나고 있습니까?
우선, 이것은 흥미로운 질문입니다. 그러나 "실제 코드"에서는 절대로 나오지 말아야합니다. 동일한 줄에서 호출하는 변수에 할당하는 것은 작동 방식을 알고 있더라도 혼란 스럽기 때문입니다.
여기서 일어나는 일은 다음 3 단계입니다.
- 메서드를 호출 할 객체를 파악합니다 (즉, 첫 번째를 평가
x
하면 문자열 "hello"에 대한 참조가 생성됨). - 매개 변수를 파악합니다 (즉, 평가 하면 String "goodbye"를 가리 키도록
x = y
변경x
되고 해당 String에 대한 참조도 반환 됨). 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));
x
before 발생이 .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
'developer tip' 카테고리의 다른 글
고양이 방법 < (0) | 2020.10.21 |
---|---|
ASP.NET MVC 5에서 사용자 지정 인증을 구현하는 방법 (0) | 2020.10.21 |
왜 (그리고 언제) sizeof 뒤에 괄호를 사용해야합니까? (0) | 2020.10.21 |
models.py를 여러 파일로 분할 (0) | 2020.10.21 |
RelativeLayout의 기준선은 무엇입니까? (0) | 2020.10.21 |