通用类型转换[重复]

2024-03-10

我有以下课程(简化但仍然是一个有效的示例):

class Test<T> {
    List<T> l = new ArrayList<>();

    public Test() {
    }

    public void add(Object o) {
        l.add((T)o);
    }
}

以及测试代码:

Test<Double> t = new Test<>();
t.add(1);
t.add(1.2);
t.add(-5.6e-2);
t.add("hello");

一切都很顺利,但这不是我所期望的。不应该是add方法抛出一个ClassCastException?如果我添加一个get方法或多或少是相同的:

    public T get(int i) {
        return l.get(i);
    }
.../...
t.get(1);             // OK.
t.get(3);             // OK (?)
Double d = t.get(3);  // throws ClassCastException

为什么只有在变量赋值时才会抛出异常?如果(T)演员阵容不起作用?


add 方法不应该抛出一个ClassCastException?

不,不应该(尽管我希望如此)。长话短说,泛型的 Java 实现在编译代码后会丢弃类型信息,因此List<T>允许采取任何Object,以及你的演员阵容add方法没有被检查。

为什么只有在变量赋值时才会抛出异常?

因为演员阵容Double由编译器插入。 Java 编译器知道返回类型get is T,即Double,因此它插入一个强制转换以匹配变量的类型d,结果被分配给它。

以下是实现泛型安全转换的方法:

class Test<T> {
    private final Class<T> cl;
    List<T> l = new ArrayList<>();

    public Test(Class<T> c) {
        cl = c;
    }

    public void add(Object o) {
        l.add(cl.cast(o));
    }
}

现在演员阵容由Class<T>对象,所以你会得到一个ClassCastException尝试插入错误类型的对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通用类型转换[重复] 的相关文章

随机推荐