为什么Java泛型不允许对泛型类型进行类型转换?

时间:2016-03-25 03:51:59

标签: java generics type-conversion

public class Main {

    public static <T> void foo(T[] bar) {
        double d = (double) bar[0]; // Error : incompatible types
    }

    public static void main(String[] args) {
        int[] int_buf = new int[8];
        foo(int_buf);
    }
}

问题在代码中显示。

为什么Java泛型不允许对泛型类型进行类型转换?

3 个答案:

答案 0 :(得分:15)

问题比这更深刻。即使没有突出显示的行,该程序也会被破坏:

public class Main {
    public static <T> void foo(T[] bar) {
        // do nothing
    }

    public static void main(String[] args) {
        int[] int_buf = new int[8];
        foo(int_buf);   <-- problem is here
   }
}

Java泛型仅支持引用类型作为类型参数;泛型方法foo()可以重写如下:

<T extends Object> void foo(T[] bar) { ... }

这就是你的问题:T没有Object延伸int[]T[]T

其次,转换失败的原因是我们对T一无所知,因此我们不知道存在从doublenumberTracker = {1,15,6,8}的转换。

答案 1 :(得分:13)

这是因为您没有指定泛型类型T是什么。因此,默认情况下,它会认为T是对象类型,而不是数字。将对象强制转换为double是不可能的,这没有任何意义。

如果您更改为<T extends Number>,这应该可以正常工作。虽然,您可能需要一个Integer数组而不是一个int数组

答案 2 :(得分:-2)

Java编译器会删除通用代码中的所有类型参数。这样做的直接后果是您无法验证当前使用的通用参数化类型。如果您进行测试,instanceof也将无效。由于运行时没有跟踪java中的类型参数,因此HashSet<Integer>HashSet<Double>之间没有区别。您最多可以执行..instanceof HashSet<?>来检查它是否是HashSet的实例。

如果我所写的内容不明确,请参阅docs

相关问题