(i <= j && j <= i && i! = j)가 TRUE로 평가되는 이유는 무엇입니까?


104

무한 루프에서 실행되는 Java 코드를 작성했습니다.

다음은 코드입니다.

public class TestProgram {
    public static void main(String[] args){
        Integer i = new Integer(0);
        Integer j = new Integer(0);

        while(i<=j && j<=i && i!=j){
            System.out.println(i);
        }
    }
}

위의 코드에서 while루프 에서 조건을 확인하는 동안 처음에는 해당 프로그램이 while루프 내부로 들어 가지 않는 것처럼 보입니다 . 그러나 실제로는 무한 루프이며 값을 계속 인쇄합니다.

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


8
간단한 대답은 i<=j && j<=i && i!=j이 조건이 항상 참으로 평가된다는 것입니다. 그냥 종이 조각을 가지고 : 당신이 그것을 잡을 평가
프라 딥 Simha

4
정수를 만드는 방법이 잘못되었습니다. 'compareTo'사용
nachokk 2013-09-14

7
i또는을 변경하지 않으면 j언제 루프가 종료 될 것으로 예상합니까?
Fred Larson

33
@PradeepSimha 간단한 int 값의 경우 항상 false를 생성 합니다. 에서 i<=jj<=i그, 당신은 결론을 내릴 수있다 i == j마지막으로 용어 모순되는. 따라서 전체 표현식은 거짓으로 평가되고 while은 입력되지 않습니다. 요점은 여기서 객체 정체성입니다!
Sirko 2013-09-14

4
제쳐두고, 이것은 Java Puzzlers : Traps, Pitfalls 및 Corner Cases 책의 퍼즐 32입니다.
Cyanfish

답변:


188
  • i <= j로 평가된다 true자동 언 박싱은 INT 비교에 발생 후 모두 있기 때문에, i그리고 j기본값을 개최 0.

  • j <= itrue위의 이유 때문에 평가됩니다 .

  • i != jtrue둘 다 다른 객체 이기 때문에 로 평가됩니다 . 그리고 개체를 비교하는 동안 자동 언 박싱이 필요하지 않습니다.ij

모든 조건에 해당합니다, 당신은 변경되지 않습니다 ij는 무한히 실행되도록, 루프.


10
왜! =가 참조 객체의 메모리 인덱스를 확인하고 <=가 Integer의 unboxed 값을 확인하고 있는지 설명해 주시겠습니까? ?? .. 왜 이러한 연산자 사이에 이러한 차이가 있습니까?
Punith Raj 2013

41
@PunithRaj <&> 연산자는 객체가 아닌 기본 요소에서 작동하므로 이러한 연산자에 대해 자동 언 박싱이 발생합니다. 그러나 == 및! = 연산자는 객체 비교에도 사용할 수 있으므로 여기서 unboxing이 필요하지 않으므로 객체가 비교됩니다.
Juned Ahsan 2013 년

14
아, 암묵적 복싱 / 언 박싱의 숨겨진 위험 !!
Hot Licks 2013 년

3
Stack Overflow는 "자동 언 박싱은 Java에서 가장 큰 실수였습니다"라는 새 태그를 추가해야합니다. :-). Java Puzzler 책의 작가를 제외하고. 이러한 질문에 태그를 지정하는 데 사용합니다.
user949300

4
참고 Integer.valueOf(0) == Integer.valueOf(0)이 경우 동일한 개체가 반환되기 때문에 항상 true로 평가된다 (IntegerCache의 참조 grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/...를 )
Vitalii Fedorenko

40

당신이 비교하고 있기 때문에

  • 0 < = 0 (true) // unboxing

  • 0 > = 0 (true) // unboxing

  • reference != secondReference (true)원시 비교가 아닌 객체를 생성 할 때 따라서 while(true) { // Never ending loop }.


2
오! 자동 UNBOXING의 숨겨진 드래곤 ... 좋은 설명.
HybrisHelp

17

정수 개체가 다릅니다. 기본 int 유형과 다릅니다.

이 답변을 참조하십시오 : Java에서 두 정수를 올바르게 비교하는 방법은 무엇입니까?

i != j부분은 사실이며, 당신은 거짓 일 것으로 예상했습니다.


사실이지만 여기서는 중요하지 않으며 질문에 대한 답변도 아닙니다.
Kon

6
@Kon : 사실 이것이 답입니다. 조건 # 1 및 # 2 true는 오토 박싱 때문에 평가됩니다 . # 3의 경우 오토 박싱이 적용되지 않고 객체 (메모리 위치) 수준에서 비교가 이루어집니다.
home

1

조건이 true이기 때문에 루프가 끝나지 않습니다 (i! = j는 true입니다. 2 개의 다른 객체가 있기 때문에 대신 Integer.valueOf 사용). 루프 내부에서 값이 변경되지 않으므로 조건이 영원히 참으로 유지됩니다.


1

정수 개체가 다릅니다. 기본 int 유형과 다릅니다. 그렇게 할 수 있습니다. 당신이하는 일은 단지 대상을 비교하는 것이고 물론 그 결과는 사실입니다.


1

먼저 이해해야 할 두 가지 경우가 있습니다.

사례 1 :

        Integer i = new Integer(10);
        Integer j = new Integer(10);

        System.out.println((i<=j && j<=i && i!=j));
        System.out.println(i!=j);

사례 2 :

        Integer i = 10;
        Integer j = 10;

        System.out.println((i<=j && j<=i && i==j));
        System.out.println(i==j);

둘 다 다릅니다.

경우 1 : i!=jtrue모두가 힙에 두 개의 서로 다른 개체에 대한 참조 때문에 같을 수 없습니다. 그러나

사례 2 : i==jtrue모두 (10)는 정수 리터럴 및 Java는 유지하므로 pool for Integer literals값이있는 (-128 <= X <= 127). 따라서이 경우 10 <= 127 결과가 true이므로 둘 다 동일한 객체를 참조하게됩니다.


0

아마도 그 이유는 'i'와 'j'가 모두 객체이고 객체 비교가 객체 참조 비교와 동일하지 않기 때문일 것입니다. i! = j 대신! i.equals (j) 사용을 고려하십시오.


0

이 프로그램은 동일한 값 표시에 유지 i당신이 증가 또는 감소시키는 하나의 값이되지 않기 때문에 i또는 j. for의 조건은 항상 true로 평가되므로 무한 루프입니다.


i!=j의외로 <=비교가 아닌 사실로 평가 되는 부분 에 대한 질문이라고 생각합니다 .
Soravux 2013 년

0

정수 a = new Integer (0); 정수 b = new Integer (0);

<= 및> = 비교는 unboxed 값 0을 사용하는 반면! =는 참조를 비교하고 서로 다른 객체이므로 성공합니다.

이것도 작동합니다 i, e

정수 a = 1000; 정수 b = 1000;

그러나 이것은 그렇지 않습니다.

정수 a = 100; 정수 b = 100;

그 이유는 Integer가 내부적으로 -128에서 127 사이의 Integer 개체에 대해 캐싱을 사용하고 포함 된 범위에 대해 해당 캐시에서 인스턴스를 반환하기 때문입니다. 확실하지 않지만 "java.lang.Integer.IntegerCache.high"패키지에서 최대 값을 변경할 수도 있습니다.

더 나은 이해를 위해 URL 확인 : https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching


-3

&& this와 this &에서 약간 다른 것을 알아야합니다. &&를 사용할 때 첫 번째 조건이 참이면 두 번째 조건이 거짓이면 세 번째 조건을 확인하지 않았으며 한 조건이 거짓이면 & 연산자가 모두 사용하는 경우 진술은 거짓입니다 || 그런 다음 true가 표시되면 i와 j가 첫 번째이고 두 번째 조건이 true이기 때문에 코드에서 true를 반환하고 세 번째 조건에서는 같고 condition이 false이기 때문에 false입니다.


내 대답은 광산의 가치를 얻을 왜 내 대답은이 링크를 참조 사실 때문에 나는 모른다는 사실 그 전에 내 대답에 광산 읽기 얻을 더 stackoverflow.com/questions/5564410/difference-between-and
사라 Sodagari
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.