Programing

boxed Long 값 127과 128 비교

lottogame 2020. 8. 14. 08:14
반응형

boxed Long 값 127과 128 비교


조건을 사용하여 두 개의 Long 개체 값 을 비교하고 싶습니다 if. 이 값은 때 적은 128보다if조건은 제대로 작동하지만,이 경우 보다 크거나 128에 동일 비교는 실패합니다.

예:

Long num1 = 127;
Long num2 = 127;

if (num1 == num2) {
    // Works ok
}

위 코드 비교는 제대로 작동하지만 아래 코드에서는 실패합니다.

Long num1 = 128;
Long num2 = 128;

if (num1 == num2) {
    // Does NOT work
}

Long 변수를 127보다 큰 값과 비교할 때 왜 문제가 있습니까? 변수 데이터 유형이 long primitives 로 변경 되면 비교가 모든 경우에 적용됩니다.


TL; DR

Java는 boxed Integer 인스턴스를 -128에서 127. 대신 ==객체 참조 를 비교 하는 사용 하고 있으므로 캐시 된 객체 만 일치합니다. 박스되지 않은 기본 값으로 작업 하거나 객체 를 비교 하는 데 사용하십시오 .long.equals()Long

긴 (말장난 의도) 버전

Long 변수를 127보다 큰 값과 비교하는데 왜 문제가 있습니까? 위 변수의 데이터 유형이 원시 (long)이면 모든 값에 대해 코드가 작동합니다.

Java는 -128 ~ 127 범위의 Integer 개체 인스턴스를 캐시합니다 . 즉,

  • N Long 변수 값 127( cached )으로 설정하면 모든 참조가 동일한 객체 인스턴스를 가리 킵니다. (N 변수, 1 인스턴스)
  • N Long 변수로 값을 설정하면 128( 캐시되지 않음 ) 모든 참조가 가리키는 객체 인스턴스를 갖게됩니다. (N 변수, N 인스턴스)

그 이유는 다음과 같습니다.

Long val1 = 127L;
Long val2 = 127L;

System.out.println(val1 == val2);

Long val3 = 128L;
Long val4 = 128L;

System.out.println(val3 == val4);

다음을 출력합니다.


거짓

를 들어 127L의 메모리 (캐시)에 동일한 개체 인스턴스를 모두 참조 (VAL1과 val2만큼) 포인트 이후 값, 그것은 반환합니다 true.

한편,에 대한 (128) 메모리에 캐쉬 그것을위한 인스턴스가 없기 때문에 값, 새로운 하나 (val3 및 val4 가리키는) 두 가지 경우에 생성 및 리턴 박스형 값에 대한 새로운 할당을 위해 만들어 false온 그들 사이의 비교.

이는 기본 값이 아닌 두 개의 Long 객체 참조를 연산자 long비교하기 때문에 발생합니다 ==. 이 캐시 메커니즘이 아니었다면 이러한 비교는 항상 실패 할 것이므로 여기서 실제 문제는 박스형 값을 ==연산자 와 비교하는 것 입니다.

이러한 변수를 기본 long유형으로 변경하면 이런 일이 발생하지 않지만 Long객체를 사용하여 코드를 유지해야하는 경우 다음 접근 방식으로 안전하게 이러한 비교를 수행 할 수 있습니다.

System.out.println(val3.equals(val4));                     // true
System.out.println(val3.longValue() == val4.longValue());  // true
System.out.println((long)val3 == (long)val4);              // true

(캐스트에도 적절한 null 검사 필요)

IMO , 객체 비교를 처리 할 때 항상 .equals () 메서드 를 사용하는 것이 좋습니다 .

참조 링크 :


Java는 -128에서 127 까지의 기본 값을 캐시합니다 . 두 개의 Long 객체를 비교할 때 java는 내부적으로 원시 값으로 형변환하고 비교합니다. 그러나 127 이상에서는 Long 객체가 유형 카스트를 얻지 못합니다. Java는 .valueOf () 메소드로 출력을 캐시합니다 .

이 캐싱은 -128에서 127까지 Byte, Short, Long에 대해 작동합니다. Integer 캐싱의 경우 -128에서 java.lang.Integer.IntegerCache.high 또는 127 중 더 큰 값으로 작동합니다. (우리는 Integer 값까지 최상위 값을 설정할 수 있습니다. java.lang.Integer.IntegerCache.high를 사용하여 캐시되어야합니다).

 For example:
    If we set java.lang.Integer.IntegerCache.high=500;
    then values from -128 to 500 will get cached and 

    Integer a=498;
    Integer b=499;
    System.out.println(a==b)

    Output will be "true".

Float 및 Double 개체는 캐시되지 않습니다.

캐릭터는 0에서 127까지 캐시를 얻습니다.

You are comparing two objects. so == operator will check equality of object references. There are following ways to do it.

1) type cast both objects into primitive values and compare

    (long)val3 == (long)val4

2) read value of object and compare

    val3.longValue() == val4.longValue()

3) Use equals() method on object comparison.

    val3.equals(val4);  

num1 and num2 are Long objects. You should be using equals() to compare them. == comparison might work sometimes because of the way JVM boxes primitives, but don't depend on it.

if (num1.equals(num1))
{
 //code
}

Comparing non-primitives (aka Objects) in Java with == compares their reference instead of their values. Long is a class and thus Long values are Objects.

The problem is that the Java Developers wanted people to use Long like they used long to provide compatibility, which led to the concept of autoboxing, which is essentially the feature, that long-values will be changed to Long-Objects and vice versa as needed. The behaviour of autoboxing is not exactly predictable all the time though, as it is not completely specified.

So to be safe and to have predictable results always use .equals() to compare objects and do not rely on autoboxing in this case:

Long num1 = 127, num2 = 127;
if(num1.equals(num2)) { iWillBeExecutedAlways(); }

참고URL : https://stackoverflow.com/questions/20541636/comparing-boxed-long-values-127-and-128

반응형