如何从参数化列表<t>创建泛型类型T的新对象

时间:2018-04-20 10:34:29

标签: java generics

我有以下java示例类:

adb shell dumpsys meminfo | awk -F'[: ]' '/mobile_cep/ { print $1 }'

正在生成编译器警告:

  

类型安全:未捕获来自捕获#1​​的投射?将Object扩展为T

如果我这样做,我可以完美地获得确切的T对象:

public class TestClass {

    public static <T> void method(List<T> objects) throws Exception {
        for (int i = 0; i < objects.size(); i++) {
            // Create new object of the same class
            T obj = (T) objects.get(i).getClass().newInstance();
        }
    }
}

它完全知道的是T型。

为什么我无法创建该类的新实例?我怎么能解决它?

(我不是在寻找类型的回复:'添加@SuppressWarnings(“未选中”)')

3 个答案:

答案 0 :(得分:11)

这是因为getClass()返回Class<? extends Object>。你不能(安全地)将通配符?强制转换为任何东西,甚至不是通用的类类型。这是Java Generics的限制。但是,既然您可以确定此警告不是问题,您可以放心地忽略或禁止它。

但这是一种解决方法,许多应用程序和库都这样做:

public static <T> void method(List<T> objects, Class<T> clazz) throws Exception {
    for (int i = 0; i < objects.size(); i++) {
        // Create new object of the same class
        T obj = clazz.newInstance();
    }
}

答案 1 :(得分:4)

泛型在运行时被删除。因此,在列表的已声明getClass()元素上调用T将返回<? extends Object>类实例。

确实

Object.getClass()个州:

  

实际结果类型为Class<? extends |X|>,其中|X|为   擦除getClass所在表达式的静态类型   调用。

要调用newInstance()并创建T实例,您需要知道要实例化的Class实例,但请注意List可以包含任何子类T,因此将类作为参数传递可能还不够。

例如:

List<Animal> list = new ArrayList<>();
list.add(new Lion());
list.add(new Rabbit());
list.add(new Turtle());

现在调用了哪一个?

method(list, Lion.class); 
method(list, Rabbit.class);
method(list, Turtle.class);

任何人都无法编译!所以这显然是不够的 因此,我认为通过抑制警告来保留原始代码更有意义。通过这种方式,您可以确保创建与列表中的实际元素相同的类的实例:

public static <T> void method(List<T> objects) throws Exception {
    for (int i = 0; i < objects.size(); i++) {
        // Create new object of the same class
        @SuppressWarnings("unchecked")
        T obj = (T) objects.get(i).getClass().newInstance();
        System.out.println(obj);
    }
}

答案 2 :(得分:1)

  

为什么我无法创建该类的新实例?

你是。您的代码将编译并且它将按预期工作,但编译器并不是100%确定,因为类型擦除这就是您收到警告的原因。这里要注意的重要一点是警告与错误不同。

  

(我不是在寻找类型的回复:&#39;添加@SuppressWarnings(&#34;未经检查&#34;)&#39;)

如果你查看任何使用泛型和反射相互结合的Java代码库,你会看到类型安全的被抑制警告。不幸的是,这只是生活中的一个事实。