Java 5부터는 기본 유형의 boxing / unboxing이있어서 등등 int
으로 포장되었습니다 java.lang.Integer
.
나는 (즉, 최근에 새로운 자바 프로젝트를 많이 볼 확실히 사용되는하지 (6) 경우, 적어도 버전 5의 JRE를 필요로) int
보다는 java.lang.Integer
그것이 후자를 사용하는 것이 훨씬 더 편리하지만 그것을 변환하는 몇 가지 헬퍼 메소드를 가지고로, 행 long
값 등의 알.
왜 일부는 여전히 Java에서 기본 유형을 사용합니까? 실질적인 이점이 있습니까?
답변
Joshua Bloch의 Effective Java , 항목 5 : “불필요한 오브젝트 작성을 피하십시오”에서 다음 코드 예제를 게시합니다.
public static void main(String[] args) {
Long sum = 0L; // uses Long, not long
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
실행하는 데 43 초가 걸립니다. Long을 프리미티브로 가져 가면 6.8 초로 줄어 듭니다. 이것이 프리미티브를 사용하는 이유에 대한 증거라면.
고유 가치 평등의 부족 또한 우려됩니다 ( .equals()
에 비해 상당히 장황합니다 ==
)
biziclop의 경우 :
class Biziclop {
public static void main(String[] args) {
System.out.println(new Integer(5) == new Integer(5));
System.out.println(new Integer(500) == new Integer(500));
System.out.println(Integer.valueOf(5) == Integer.valueOf(5));
System.out.println(Integer.valueOf(500) == Integer.valueOf(500));
}
}
결과 :
false
false
true
false
편집 왜 (3)이 반환 true
되고 (4)가 반환 false
됩니까?
그것들은 두 개의 다른 객체이기 때문입니다. 0에 가장 가까운 256 개의 정수 [-128; 127]는 JVM에 의해 캐시되므로 동일한 객체를 반환합니다. 그러나이 범위를 넘어 서면 캐시되지 않으므로 새 객체가 만들어집니다. 더 복잡하게하기 위해 JLS 는 최소 256 개의 플라이 웨이트를 캐시해야합니다. JVM 구현자는 원하는 경우 더 많은 것을 추가 할 수 있습니다. 즉, 가장 가까운 1024가 캐시되어 모두 true를 반환하는 시스템에서 실행될 수 있습니다 … #awkward
답변
자동 박스 해제로 인해 NPE를 찾기가 어려울 수 있습니다.
Integer in = null;
...
...
int i = in; // NPE at runtime
대부분의 경우 null 할당 in
은 위의 것보다 훨씬 덜 명확합니다.
답변
박스형은 성능이 떨어지고 더 많은 메모리가 필요합니다.
답변
기본 유형 :
int x = 1000;
int y = 1000;
이제 평가하십시오 :
x == y
그것은이다 true
. 놀랍지 않습니다. 이제 박스 타입을 사용해보십시오 :
Integer x = 1000;
Integer y = 1000;
이제 평가하십시오 :
x == y
그것은이다 false
. 아마. 런타임에 따라 다릅니다. 그 이유는 충분합니까?
답변
성능 및 메모리 문제 외에도 다른 문제 가 있습니다 . List
인터페이스 가 없으면 인터페이스 가 손상되었습니다 int
.
문제는 오버로드 된 remove()
방법 ( remove(int)
vs. remove(Object)
)입니다. remove(Integer)
항상 후자를 호출하여 해결할 수 있으므로 색인으로 요소를 제거 할 수 없습니다.
반면에 int
: 를 추가하고 제거하려고 할 때 함정이 있습니다 .
final int i = 42;
final List<Integer> list = new ArrayList<Integer>();
list.add(i); // add(Object)
list.remove(i); // remove(int) - Ouch!
답변
당신은 정말 상상할 수 있습니까
for (int i=0; i<10000; i++) {
do something
}
대신 java.lang.Integer로 루프? java.lang.Integer는 변경할 수 없으므로 루프마다 증가 할 때마다 단일 JVM 명령으로 스택에서 int를 증가시키는 대신 힙에 새로운 Java 객체를 작성합니다. 성능은 악마적일 것입니다.
나는 int보다 java.lang.Integer를 사용하는 것이 편리하다는 점에 동의하지 않습니다. 반대로. Autoboxing은 Integer를 사용해야하는 경우 int를 사용할 수 있으며 Java 컴파일러는 코드를 삽입하여 새 Integer 객체를 만듭니다. 오토 박싱은 컴파일러가 관련 객체 구성을 삽입하면서 Integer가 필요한 곳에서 int를 사용할 수있게하는 것입니다. 처음부터 int의 필요성을 제거하거나 줄이는 것은 아닙니다. 오토 박싱을 사용하면 두 세계를 모두 활용할 수 있습니다. 힙 기반 Java 객체가 필요할 때 자동으로 Integer가 생성되며 산술 및 로컬 계산을 수행 할 때 int의 속도와 효율성을 얻습니다.
답변
기본 유형은 훨씬 빠릅니다.
int i;
i++;
정수 (모든 숫자 및 문자열)는 변경할 수없는 유형입니다. 일단 작성된 후에는 변경할 수 없습니다. i
Integer 라면 i++
새로운 Integer 객체를 생성하는 것 보다 메모리와 프로세서 측면에서 훨씬 비쌉니다.
