3

这是我遇到的一个案例的缩小示例。

看看下面的代码:

class Holder<T> {
    private T t;
    public Holder(T t) {
        this.t = t;
    }
    public T getValue() {
        return t;
    }
}

public class FooMain {

    private static Object newHolder() {
        return new Holder<Integer>(3);
    }

    public static void main(String args[]) {
        Holder<String> hs = (Holder<String>) newHolder(); // line-18
        String s = hs.getValue();                         // line-19
    }
}

让我感到震惊的是,不可避免的东西ClassCastException被扔在第 19 行而不是第 18 行

因此,在你的代码中有一个类型的对象Holder<String>并不足以保证它getValue会返回一个String. 您还必须检查这个对象是如何构造的!

我知道 Type Erasure 在这里发挥了作用,但我不确定上述内容的含义有多大。在我的特殊情况下,newHolder-corresponding 方法在外部库中定义并返回java.lang.Object,因此我必须进行这些转换。

4

2 回答 2

2

编译时你会得到一个警告,说你正在执行转换,这意味着编译器不能保证类型安全。当您进行这些演员表并收到这些警告时,您基本上是靠自己的。由于泛型是在 Java 中使用擦除来实现的,因此泛型类型信息在运行时会消失 - 它纯粹是一个编译时构造,因此如果您规避这一点,运行时可能直到稍后才知道您执行了无效转换。

于 2013-06-03T13:53:05.083 回答
2

泛型是用于检查类型安全的编译时工具。在运行时没有验证,如类型 erasure。这就是为什么从整数中获取字符串时会出错的原因。

顺便说一句,您应该在投射时收到警告。忽视警告可能会产生后果......

于 2013-06-03T13:51:53.547 回答