泛型类型转换 [英] Generic Type cast

查看:96
本文介绍了泛型类型转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类(简化但仍然是一个工作示例):

  class Test< T> {
列表< T> l = new ArrayList<>();
$ b $ public Test(){
}

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


以及测试代码:

 测试< 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); // 好。
t.get(3); // OK(?)
Double d = t.get(3); //抛出ClassCastException

为什么只在变量赋值时抛出异常?如果(T)转换不起作用,我该如何执行类型一致性? 解决方案 div>


不应该使用add方法抛出 ClassCastException


不,它不应该(虽然我希望它)。长话短说,编译代码后Java的泛型实现丢弃了类型信息,所以 List< T> 可以接受任何 Object ,并且你的 add 方法中的强制转换不会被检查。


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


因为转换为 Double 由编译器插入。 Java编译器知道 get 的返回类型是 T ,它是 Double ,因此它会插入一个强制类型以匹配变量 d 的类型,结果将被赋值给它。



以下是您可以如何实现通用安全的强制转换:

  class Test< T> {
private final Class< T> CL;
列表< T> l = new ArrayList<>();

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

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






现在转换由 Class< T> 对象,因此尝试插入不正确类型的对象时,您将得到 ClassCastException


I have the following class (simplified but still a working example):

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

    public Test() {
    }

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

And the test code:

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

Everything is working fine, and that's not what I was expecting. Shouldn't the add method throw a ClassCastException? If I add a get method that's more or less the same thing:

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

Why is it only on variable assignment that the exception is thrown? How can I enforce type consistency if the (T) cast doesn't work?

解决方案

Shouldn't the add method throw a ClassCastException?

No, it shouldn't (although I wish it did). Long story short, Java implementation of generics discards type information after compiling your code, so List<T> is allowed to take any Object, and the cast inside your add method is not checked.

Why is it only on variable assignment that the exception is thrown?

Because the cast to Double there is inserted by the compiler. Java compiler knows that the return type of get is T, which is Double, so it inserts a cast to match the type of the variable d, to which the result is being assigned.

Here is how you can implement a generic-safe cast:

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));
    }
}

Now the cast is performed by a Class<T> object, so you will get a ClassCastException on an attempt to insert an object of an incorrect type.

这篇关于泛型类型转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆