문제

import java.lang.reflect.Array;

public class PrimitiveArrayGeneric {
    static <T> T[] genericArrayNewInstance(Class<T> componentType) {
        return (T[]) Array.newInstance(componentType, 0);
    }

    public static void main(String args[]) {
        int[] intArray;
        Integer[] integerArray;

        intArray = (int[]) Array.newInstance(int.class, 0);
        // Okay!

        integerArray = genericArrayNewInstance(Integer.class);
        // Okay!

        intArray = genericArrayNewInstance(int.class);
        // Compile time error:
           // cannot convert from Integer[] to int[]

        integerArray = genericArrayNewInstance(int.class);
        // Run time error:
           // ClassCastException: [I cannot be cast to [Ljava.lang.Object;
    }    
}

하는 방법을 완전히 이해하 제네릭 자바에서 작동.일상에서 나를 위해 제 3 할당에서 위와 같은 코드:컴파일러가는 불평 Integer[] 으로 변환할 수 없 int[].문의 100%에 해당 물론,하지만 내가 궁금해 컴파일러를 만들이다.

당신이 언급하는 경우는 라인과 따라 컴파일러의"제안서와 같이"4 할당 컴파일러가 실제로 만족!!! 지금 코드를 컴파일하고 괜찮습니다!는 미친은 물론,이 같은 실행 시간이 행동을 제안, int[] 으로 변환할 수 없 Object[] (는 무엇인 T[] 의 형식이 삭제로에서 실행 시간).

그래서 제 질문은:왜 컴파일러는 제안""나는 할당 Integer[] 대신에 대한 제 3 할당?어떻게 컴파일러는 이유로 도착하는 것(잘못된!) 결론입니까?


많은 혼란에서 두 개의 답변이 지금까지,그래서 내가 만들어진 또 다른 이해를 들어 설명하기 위해 근본적인 문제는 여기:

public class PrimitiveClassGeneric {    
    static <T extends Number> T test(Class<T> c) {
        System.out.println(c.getName() + " extends " + c.getSuperclass());
        return (T) null;
    }
    public static void main(String args[]) {
        test(Integer.class);
        // "java.lang.Integer extends class java.lang.Number"

        test(int.class);
        // "int extends null"
    }
}

나는 생각하는 그것의 절대적으로 미치는 컴파일할 수 있는 위의 코드를 컴파일되는?

지 않는 것이 불합리하는 인쇄 c.getSuperclass().getName() 위 코드에서이기 때문에,예를 들어 내가 지정하는 T extends Number.물론 지금 getName() 을 던져 NullPointerExceptionc == int.class, 이후 c.getSuperclass() == null.

고,나에게는 아주 좋은 이유를 거부하는 코드에서 컴파일에 첫 번째 장소입니다.


아마도 궁극적 발광:

    int.class.cast(null);

는 코드를 컴파일 실행 괜찮습니다.

도움이 되었습니까?

해결책

의 유형 int.classClass<Integer>, 래 genericArrayNewInstance() 것 유추를 반환 Integer[].하지만 실제로 기능을 만듭니다 int[], 그래서 그는 클래스를 던지는 경우는 예외 그것이 반환됩니다.기본적으로 캐스팅 T[] 내부 기능이 적법하지 않기 때문에 이 경우에는 int[]T[] (기본 요소에서 사용할 수 없 유형 변수).당신은 처리할 수 없는 원시적인 배열 형식은 일반적으로;그래서 당신이 있어야의 방법으로 입력 Object, 또는 당신은 별도의 방법을 참조를 위해 유형에 대한 기본 형식.

다른 팁

몇 가지 요점 :

  1. 프리미티브입니다 자가 옥스 필요할 때 물체에 대응하는 사람 (포장지)
  2. 원시 어레이는 물체이므로자가 공산이 없습니다.
  3. 제네릭은 프리미티브를 유형 매개 변수로 사용할 수 없습니다

예를 들어 내 가정은 다음과 같습니다.

3에서자가 옥싱이 발생합니다 유형 매개 변수, 그러나 반환 된 배열에는 일어나지 않습니다
4에서자가 옥싱이 발생합니다 유형 매개 변수, 그러나 발생하지 않습니다 방법 인수, 실제로 int[] 생성되지만 Integer[] 예상됩니다

유형 매개 변수의 경우 자서전은 정확히 그렇지 않을 수 있습니다. 오토 옥싱, 그러나 같은 생각을 가진 것입니다.

업데이트: 두 번째 예제에는 아무런 문제가 없습니다. int.class a Class, 따라서 컴파일러는 거부 할 이유가 없습니다.

원래 포스터에 동의합니다. 이것은 미쳤다. 왜 Generic과 Primitive를 사용할 수 없습니까? 이것은 컴파일러 문제가 아니지만 언어 문제입니다. 일반에서 원시 유형을 건너 뛰는 것은 단순히 잘못되었습니다.

이것을 위해 :

intarray = (int []) array.newinstance (int.class, 0);

int.class는 단지 클래스 객체입니다. 따라서 지나도 괜찮습니다. "int"는 유형이므로 명확하게 원시적이기 때문에 괜찮지 않습니다. 말할 것도없이 언어를 고수하기 위해 언어를 만들 수있는 "가장 좋은"방법이라고 말할 수는 없습니다.

이것은 너무 미쳤으므로 제네릭을 사용하여 프리미티브의 메모리 (배열) 할당을위한 래퍼를 만들 수 없습니다. 물체를 사용하는 경우, 그것은 낭비적인 거대한 컬렉션에 너무 부풀어 오릅니다. Java 언어/기계를 만든 사람들은 분명히 뇌에 약간의 한계가 있습니다. 그들은 첫 번째로 잘못 할 수 있지만 10 년이 걸리고 제대로하지 않아야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top