2013-10-22 1 views
9

나는 다음을 수행자바는 오토 박싱하지 않는 이유 INT [] 정수 []

  • arrayList1가 - 하나 개의 요소를 포함하고 그것이 int[]입니다.

    int[] intArray = new int[]{2,3,4,5,6,7,8}; 
    ArrayList arrayList1 = new ArrayList(Arrays.asList(intArray)); 
    ArrayList<Integer> arrayList2 = new ArrayList<Integer>(Arrays.asList(intArray)); 
    
    Integer[] integerArray = new Integer[]{2,3,4,5,6,7,8}; 
    ArrayList<Integer> arrayList3 = new ArrayList<Integer>(Arrays.asList(integerArray)); 
    

    질문 :

  • arrayList2 - : - 컴파일하지 (7 개) 요소를 포함하고 그들은 Integer 객체 여기

있는 코드 것

  • arrayList3는 (오류 생성자 ArrayList<Integer>(List<int[]>)은 정의되지 않습니다) 컴파일러가 int[] ~ Integer의 요소를 자동 상자로 표시하지 않는 이유는 무엇입니까? ArrayList<Integer>을 만드시겠습니까? 이 이유는 무엇입니까? 그게 내 어리 석음인가 또 다른 이유인가?

  • 답변

    12

    차이점은 int[] 자체는 Object이며, Integer[]Integer 개체에 대한 참조 배열입니다.

    Arrays.asList(T...) 메서드는 상한 일부 유형 T 가변 인수 걸린다. 이 방법의 삭제는 Arrays.asList(Object...)입니다. 즉, Object에서 확장되는 모든 유형의 다양한 인수를 취할 것입니다. 내부적 인 T...합니다 (T[] 어레이의 첫 번째 요소로 갈 것이다 int 이후

    Object하지만 원시 형 아니므 int[]Object 자체 인 반면, 그것은 T[] 개별 요소로 전달 될 수 없다 a T[] 만 해당). 그러나 Integer[]T[]-Integer[] 전달 같은 다른 인자에 각각 참조하여 T[]로 전달한다.

    그리고 심지어 컴파일러가 int[] 배열의 각 요소를 Integer으로 변환해야한다고 주장하더라도 컴파일러에서 너무 많은 작업이 필요합니다. 먼저 내부적으로 이러한 요소에서 Integer[]를 만들려면 다음이 필요, Integer에 각 배열 요소를 가지고 가고, 상자해야합니다. 그게 너무 많아. 이미 int[]에서 Object으로 직접 변환됩니다. 난 항상달라고했지만 자바 제네릭과 함께 작업하는 동안 간단한 생활을 만들었을 것 int[]에서 Integer[]에 암시 적 변환을 허용하지만, 다시 그 언어가 설계 방법입니다.

    는 간단한 예를 보자

    Object[] array = new Integer[10]; // this is valid conversion 
    Object[] array2 = new int[10];  // this is not 
    Object obj = new int[10];   // this is again a valid conversion 
    

    그래서, 코드에서 Arrays.asList(intArray)ArrayList<int[]>하지 ArrayList<Integer> 반환합니다. ArrayList<Integer>() 생성자에 전달할 수 없습니다.관련


    :

    +0

    고맙습니다. 알았다! – namalfernandolk

    +0

    @NamalFernando 환영합니다 :) –

    1

    int[]Integer[] 때문에 모두가 개체입니다. 먼저 int 프리미티브 값이 입력되고 Object 유형이 아니며 Integer 개체의 참조가 저장됩니다 (Object).

    +0

    Ok. 알았다. 고맙습니다! – namalfernandolk

    3

    int[]하지Integer[] 동일하다.

    An array has as associated Class object. 프리미티브 int 배열의 클래스 객체는 [I입니다. Integer 배열의 클래스 개체는 [Ljava/lang/Integer입니다.

    배열 자체는 객체이므로 동일한 유형의 두 객체 (is an identity conversion) 사이를 변환합니다. 위의 바이트 코드에 의해 입증 된 바와 같이, 두 개의 다른 유형의 객체간에 변환하는 것은 다릅니다. int[]Integer[]은 분명히 다릅니다.

    마지막으로, 자동 저장은 there was an associated boxing conversion 인 경우에만 실제로 적용됩니다.

    +0

    감사합니다. 귀하의 답변과 참고 문헌은 많은 도움이됩니다. – namalfernandolk

    +0

    '[I]에 대한 참조로드/저장 연산을 사용할 수있는 방식으로 VM을 설계 할 수 있습니다. [[L]의 정수로드/저장 연산, 이러한 연산이 실패 할 수 있음을주의해야합니다 타입 변환 오류; 이것이 완료 되었다면,'int []'를'Integer []'로 사용할 수 있습니다. 가장 큰 어려움은 (1)'int [] '를'Integer []'를 기대하는 코드에 넘겨 주거나 그 반대의 경우는 엄청난 스피드 페널티를 초래할 것입니다. (2)''L '이 던져 버릴 수있는'null '을 저장하고,''Integer''처럼 보이는 것을''Integer''로 저장하고 그것을 다시 읽으려는 시도 ... – supercat

    +0

    ... 다른 것을 얻을 수 있습니다. 건네받은 것의 오브젝트. 상세한 해답은 – supercat

    2

    기술적으로는 물론 가능합니다. 그러나 래퍼 유형 배열에 원시 형식 배열의 autoboxing/unboxing은 예상 한 것 이상입니다.

    Java의 자동 복싱/압축 해제 기능을 처음 살펴보십시오. 원시 래퍼 코드를 입력하는 대신 간단히 구문 설탕을 사용합니다. 예 :

    Integer i = 10; 
    
    컴파일러는이 Integer을 기대하고 있음을 알고

    , 대신 현재 int.

    Integer i = Integer.valueOf(10); 
    

    그것은 언 박싱 비슷한 일을한다 : 상황이 int하지만 Integer가 존재 기대하는 경우는, 컴파일러 돌아 가기 배열에 varName.intValue()

    로 교체 따라서 어떤 컴파일러가 일을하는 것은 당신의 코드를 변환하는 것입니다. 우리가 생각할 수있는 두 가지 문제가 있습니다 :

    첫 번째 문제는 int 배열에서 Integer 배열로 변환하는 직접적인 방법이 없다는 것입니다. 당신은 컴파일러가

    int[] intArray = ....; 
    Integer[] wrapperArray = intArray ; 
    

    Integer[] wrapperArray = new Integer[intArray.size()]; 
    for (int i = 0; i < intArray.size(); i++) { 
        wrapperArray[i] = Integer.valueOf(intArray[i]); 
    } 
    

    을 변화시킬 수 있다고 주장 할 수 있지만, 구문 설탕을 너무 많이 보인다.

    두 번째 큰 문제는 메서드에 매개 변수로 전달할 때 배열에 autoboxing/unboxing이 발생하면 원래 배열의 참조가 전달되는 대신 이제는 해당 배열의 복사본에 대한 참조를 전달하는 것입니다. 원래 배열.메서드에서 배열의 내용을 변경하는 경우 원본 배열은 영향을받지 않습니다. 그것은 당신에게 많은 놀라움을 가져올 수 있습니다.

    void foo(Integer[] arr) { 
        arr[0] = 0; 
    } 
    
    // invoking foo in some code: 
    int[] intArr = new int[]{9,8,7,6}; 
    foo(intArr); 
    // intArr[0] will still be 9, instead of 0 
    
    +0

    +1. StackOverFlow에는 여러 개의 대답을 받아 들일 수있는 옵션이 있어야합니다. – namalfernandolk

    +0

    @NamalFernando 칭찬에 감사드립니다. 불행히도 SO는 그러한 기능을 제공하지 않지만 현상금을 무료로 수여합니다;) –

    1

    arrayList1은 실제로 크기 1의 목록입니다.

    http://ideone.com/w0b1vY

    arrayList1.size() = 1 
    arrayList3.size() = 7 
    

    INT []

    은 단일 객체로 캐스팅되고있다. 그 Object는 Integer로 변환 될 수 없습니다.

    +1

    감사합니다. 너의 대답을 얻었다. 그러나 내 걱정은 그것이 왜 autoboxing이 아니 었는가? 어떤 방법 으로든 나는 Rohit에서 그것을 얻었다. – namalfernandolk