gpt4 book ai didi

java - 如何在没有编译器警告的情况下使用泛型将 java.lang.Class 类型的变量初始化为 Collection?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:05:55 30 4
gpt4 key购买 nike

我需要初始化一个 Class<Set<String>> 类型的变量

当我使用 Set.class 时,它返回 Class<Set> 的变量

Class<Set> clazz = Set.class;

当我尝试

Class<Set<String>> clazz = Set<String>.class;

我有一个编译错误。

最佳答案

首先,您需要了解,在运行时,只有一个 Class表示 Set 的对象界面。没有单独的 Class Set<String> 的对象, Set<Integer> , 等等 所以你的变量类型最多 Class<Set<String>>运行时能做的就是指向这个Set类对象,问题是这样做有意义吗?

让我们考虑一下您可以使用 Class<Set<String>> 类型的变量做什么.

  • 你可以称它为.cast()方法。通常,如果你有一个 Class<T> clazz , clazz.cast(x)返回类型 T ,它在运行时所做的是检查传递的对象是否是该类的实例,如果不是,则抛出异常;这就是为什么它返回类型 T 是安全的.但是,如果您的变量指向 Class表示 Set 的对象界面,然后是它的.cast()只能检查对象是否是 Set 的实例,并不是说它是 Set<String> 的一个实例(无论如何这是不可能的,因为对象在运行时不知道它们的通用类型参数;如果你做了一个转换 (Set<String>)x ,它会给出一个未经检查的转换警告;所以如果你能够“绕过”它就没有意义通过在没有警告的情况下执行 Set<String>.class.cast(x) 来发出警告),因此它不能“安全地”返回类型 Set<String> .
  • 你可以称它为.isInstance()方法。通常,如果你有一个 Class<T> clazz , clazz.isInstance(x)根据传递的对象是否是 T 的实例返回 true 或 false .但只有 .cast() , 无法在运行时检查对象的泛型类型参数,因此调用 Class<Set<String>>.isInstance()方法可能不会给出“正确”的答案。
  • 您可以通过调用 .newInstance() 创建一个新实例方法或通过获取构造函数并使用构造函数的 .newInstance()方法。那么,在这种情况下,Set是一个接口(interface),不能被实例化;让我们考虑说,HashSet .用Class<HashSet<String>> ,您可以调用.newInstance()得到 HashSet<String>使用无参数构造函数。在这种情况下,它是安全的,因为 new HashSet() 之间没有区别。和 new HashSet<String>()new HashSet<Integer>()在运行时。但是,如果您获得带参数的构造函数,则类型 T 可能不安全。在参数中使用,因为它无法检查传递的参数是否与这些类型匹配(因为它在运行时不知道 T)。

如您所见,Class<Set<String>>无法安全地履行 Class 的契约(Contract)类的一些功能。因此,您应该无法获得 Class<Set<String>>。没有警告。如果您确定您的用例是安全的,请考虑 Class表示 Set 的对象作为 Class<Set<String>> , 然后你可以通过执行 (Class<Set<?>>)(Class<?>)Set.class 来手动强制它,但您会收到警告,这意味着您有责任确保其安全。

关于java - 如何在没有编译器警告的情况下使用泛型将 java.lang.Class 类型的变量初始化为 Collection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55560547/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com