当前位置: 首页 > 知识库问答 >
问题:

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

龙繁
2023-03-14

我有以下java示例类:

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

它正在生成编译器警告:

类型安全:从捕获#1-of?扩展对象到T的未检查强制转换

我完全可以得到精确的T对象,如果我这样做:

T obj = objects.get(i);

它完全知道这是T型的。

为什么我不能创建该类的新实例?我怎样才能修复它?

(我没有查找类型为“Add@SuppressWarnings(“unchecked”)”的响应)

共有3个答案

艾宏远
2023-03-14

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

你是的。您的代码将进行编译,并按预期工作,但编译器不能百分之百确定这一点,因为类型擦除是您收到警告的原因。这里需要注意的重要一点是,警告与错误不同。

(我没有查找类型为“Add@SuppressWarnings(“unchecked”)”的响应)

如果您查看任何相互使用泛型和反射的Java代码库,您将看到关于类型安全的禁止警告。不幸的是,这只是生活中的一个事实。

习狐若
2023-03-14

泛型在运行时被擦除。因此,在列表的声明T元素上调用getClass()会返回一个

Object.getClass()确实声明:

实际结果类型为Class

要调用newInstance()并创建T的实例,您需要知道要实例化的实例,但请注意,列表可以包含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);
    }
}

夏侯昊明
2023-03-14

这是因为getClass()返回一个

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

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

 类似资料:
  • 问题内容: 如何创建泛型类型的数组?通用方法如何工作?它返回通用数组的副本。因此可以创建通用数组。但是如何?怎么能写一个类似的方法呢? 问题答案: 如果需要在运行时创建它,则至少需要在此时知道类型,因此可以使用以下方法: where 是泛型类型,是的类,并且是初始大小。 这里的文件

  • 问题内容: 的Java,C#和打字稿(亦称语言的太阳/ Hejlsberg家庭)使用,,等来表示泛型类型参数。从表面上看,这是因为代表“ Type”,然后跟随字母。 在另一方面,Scala的使用,,等,和OCaml中和Haskell的使用,和。 这些约定从何而来?难道是因为函数式语言更接近数学证明,在那里,和被用约定? 问题答案: 在标准Java SE API中,设计人员通常选择一个与类型参数的含

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 我有很多实体扩展了实体,也有很多数据扩展到 我有一个通用的存储库、服务和映射器,如下所示 我的仓库: 我的服务: 我的地图绘制者: 我想在方法中从T创建一个对象,在类中从方法中从Dto创建一个对象

  • 我正在修改open JDK以添加特性,我已经遇到了两次,但没有好的解决方案。