이 코드 줄이 다른 값을 반환하는 이유를 모르겠습니다.
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
출력은 다음과 같습니다.
true
false
true
첫 번째 것은 왜 돌아가고 true
두 번째는 돌아 오는가 false
? 127
와 사이에 모르는 것이 128
있습니까? (물론 나는 그것을 알고 있습니다 127
< 128
.)
또한 왜 세 번째가 돌아 옵니까 true
?
이 질문에 대한 답변 을 읽었 지만 여전히 어떻게 반환 할 수 있는지 true
, 왜 두 번째 줄의 코드 가 반환되는지 알지 못했습니다 false
.
답변
여기에는 놀라운 차이가 있습니다.
valueOf
Integer
-128과 127 사이에 캐시 된 값을 가질 수 있는 객체를 반환합니다 . 이것이 첫 번째 값이 반환되는 이유 true
-캐싱 된-두 번째 값이 반환 되는-128이 false
캐싱 된 값이 아니기 때문에 두 개의 개별 Integer
인스턴스를 얻습니다. .
그것은주의하는 것이 중요하다 당신이 참조를 비교하는 것을 Integer#valueOf
, 당신은 무엇을 캐시가 지원하는보다 큰 값을 비교하는 경우, 그것은 것입니다 하지 에 평가 true
구문 분석 된 값이 동일하더라도, (적절한 예 : Integer.valueOf(128) == Integer.valueOf(128)
). 당신은 해야한다 사용 equals()
하는 대신.
parseInt
프리미티브를 반환합니다 int
. 이 세 번째 값을 반환 왜 true
– 128 == 128
, 평가, 물론입니다 true
.
이제 세 번째 결과를 만드는 데 약간의 어려움이 있습니다 true
.
-
언 박싱 변환이 발생 즉, – 당신이 사용하고있는 등가 연산자와 당신이 가지고있는 데이터 유형에 대한
int
및Integer
. 당신은을 얻고Integer
에서valueOf
물론, 오른쪽에. -
변환 후 두 개의 기본
int
값을 비교 합니다. 프리미티브와 관련하여 예상 한대로 비교가 이루어 지므로128
와 를 비교할 수128
있습니다.
답변
이 Integer
클래스에는 Integer
-128에서 127 사이의 모든 값에 대해 하나씩 256 개의 특수 객체 를 저장하는 정적 캐시가 있습니다 .이를 염두에두고이 세 가지의 차이점을 고려하십시오.
new Integer(123);
이것은 (분명히) 아주 새로운 Integer
대상을 만듭니다.
Integer.parseInt("123");
이 int
구문 분석 후 프리미티브 값을 반환 합니다 String
.
Integer.valueOf("123");
이것은 다른 것보다 더 복잡합니다. 를 파싱하여 시작합니다 String
. 그런 다음 값이 -128과 127 사이이면 정적 캐시에서 해당 객체를 반환합니다. 값이이 범위를 벗어나면 값을 호출 new Integer()
하고 전달하여 새 객체를 얻습니다.
이제 질문의 세 가지 표현을 고려하십시오.
Integer.valueOf("127")==Integer.valueOf("127");
Integer
값이 127 인 정적 캐시에서 두 번 검색되어 자체 비교 되기 때문에 true를 리턴합니다 . Integer
관련된 객체는 하나뿐 이므로이를 반환합니다 true
.
Integer.valueOf("128")==Integer.valueOf("128");
false
128은 정적 캐시에 없으므로을 반환 합니다. 따라서 Integer
평등의 각 측면에 대해 새로운 것이 만들어집니다. 두 개의 다른 Integer
객체가 있고 양쪽이 정확히 동일한 객체 인 경우 ==
에만 객체를 반환 true
하므로이 값은 false
입니다.
Integer.parseInt("128")==Integer.valueOf("128");
int
왼쪽 의 프리미티브 값 128과 Integer
오른쪽 의 새로 생성 된 객체를 비교합니다. 그것이 비교하는 것은 의미가 없기 때문에 그러나 int
에를 Integer
, 자바는 자동 – 언 박싱 것 Integer
비교를하기 전에; 그래서 당신은과 비교 int
합니다 int
. 프리미티브 (128)는 그 자체와 같기 때문에을 리턴한다 true
.
답변
이 메소드에서 값을 리턴하도록주의하십시오. 위해 valueOf 메소드는 정수 인스턴스를 반환합니다 :
public static Integer valueOf(int i)
으로 parseInt의 값 (기본 타입)에있어서의 정수를 반환 :
public static int parseInt(String s) throws NumberFormatException
비교 설명 :
메모리를 절약하기 위해 래퍼 객체의 두 인스턴스는 기본 값이 같을 때 항상 ==입니다.
- 부울
- 바이트
- \ u0000에서 \ u007f까지의 문자 (7f는 10 진수로 127입니다)
- -128에서 127 사이의 짧은 정수
==를 사용하여 기본 요소와 랩퍼를 비교하면 랩퍼가 랩핑되지 않고 비교가 기본 요소와 기본 요소가됩니다.
귀하의 상황에서 (위의 규칙에 따라) :
Integer.valueOf("127")==Integer.valueOf("127")
이 표현식은 -128에서 127 사이의 Integer 값을 포함하므로 동일한 객체에 대한 참조를 비교하여 반환합니다 true
.
Integer.valueOf("128")==Integer.valueOf("128")
이 표현식은 <-128, 127>에없는 Integer 값을 포함하므로 다른 객체에 대한 참조를 비교하므로이를 반환합니다 false
.
Integer.parseInt("128")==Integer.valueOf("128")
이 표현식은 프리미티브 값 (왼쪽)과 객체 (오른쪽)에 대한 참조를 비교하여 오른손이 풀리고 그의 프리미티브 유형이 왼쪽과 비교되어 반환 true
됩니다.
답변
정수 오브젝트는 256 정수의 -128-127 사이에서 캐시합니다.
객체 참조를 == 또는 ! = 와 비교해서는 안됩니다 . 을 사용해야합니다. 대신 equals (..) 또는 더 나은-정수 대신 기본 int를 사용하십시오.
parseInt : 문자열 인수를 부호있는 10 진수 정수로 구문 분석합니다. 문자열의 문자는 모두 10 진수 여야합니다. 첫 번째 문자는 음수 값을 나타내는 ASCII 빼기 기호 ‘-‘( ‘\ u002D’) 일 수 있습니다. 인수와 기수 10이 parseInt (java.lang.String, int) 메소드에 인수로 제공된 것처럼 결과 정수 값이 리턴됩니다.
valueOf
두 번째 인수로 주어진 기수로 구문 분석 될 때 지정된 문자열에서 추출 된 값을 보유하는 Integer 오브젝트를 리턴합니다. 첫 번째 인수는 마치 인수가 parseInt (java.lang.String, int) 메소드에 제공된 것처럼 두 번째 인수로 지정된 기수의 부호있는 정수를 나타내는 것으로 해석됩니다. 결과는 문자열로 지정된 정수 값을 나타내는 Integer 객체입니다.
에 해당
new Integer(Integer.parseInt(s, radix))
기수-s 해석에 사용되는 기수
따라서 Integer.valueOf()
사이의 정수와 같으면
-128 ~ 127 조건에 따라 true를 반환합니다.
대한 lesser than
-128과 greater than
127이 제공false
답변
주어진 답변을 보완하려면 다음 사항에 유의하십시오.
public class Test {
public static void main(String... args) {
Integer a = new Integer(129);
Integer b = new Integer(129);
System.out.println(a == b);
}
}
이 코드는 다음과 같이 인쇄됩니다. false
Jay 사용자 가 허용 된 답변에 대한 의견에서 주장 했듯이 ==
객체에 연산자 를 사용할 때주의를 기울여야합니다 . 여기서 두 참조가 서로 다르기 때문에 두 참조가 동일한 지 여부를 확인하고 있습니다. 같은 가치. 객체를 비교하려면 equals
대신 메소드를 사용해야합니다 .
Integer a = new Integer(128);
Integer b = new Integer(128);
System.out.println(a.equals(b));
인쇄됩니다 : true
당신은 물어 수 있습니다 첫 번째 줄이 인쇄 된 이유를 다음 그러나 true
? . Integer.valueOf
메소드 의 소스 코드를 확인하면 다음을 볼 수 있습니다.
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
param이 IntegerCache.low
(기본값은 -128)과 IntegerCache.high
(런타임에서 최소값 127로 계산 된 ) 사이의 정수 이면 사전 할당 된 (캐시 된) 객체가 반환됩니다. 따라서 127을 매개 변수로 사용하면 동일한 캐시 된 객체에 대한 두 개의 참조를 얻고 참조를 true
비교하게됩니다.