Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在没有编译器警告的情况下将java.lang.Class类型的变量初始化为具有泛型的集合?_Java_Generics - Fatal编程技术网

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

如何在没有编译器警告的情况下将java.lang.Class类型的变量初始化为具有泛型的集合?,java,generics,Java,Generics,我需要初始化类型为Class 当我使用Set.class时,它返回class Class clazz=Set.Class; 当我尝试 Class<Set<String>> clazz = Set<String>.class; Class clazz=Set.Class; 我有一个编译错误。首先,您需要了解,在运行时,只有一个类对象表示集接口。对于Set、Set等,没有单独的Class对象。因此Class类型的变量在运行时最多只能指向这个Set类对象,问题

我需要初始化类型为
Class

当我使用Set.class时,它返回
class

Class clazz=Set.Class;
当我尝试

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

我有一个编译错误。

首先,您需要了解,在运行时,只有一个
对象表示
接口。对于
Set
Set
等,没有单独的
Class
对象。因此
Class
类型的变量在运行时最多只能指向这个
Set
类对象,问题是这样做有意义吗

让我们考虑使用类型变量<代码>类< /代码> >

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

如您所见,<代码>类< /代码>不能安全地履行<代码>类< /代码>类的某些功能。因此,在没有警告的情况下,您不应该能够获得<代码>类< /代码>。如果您确信用例是安全的,请考虑<代码>类< <代码>对象,表示“代码> SET >作为

Class
,然后您可以通过执行
(Class)Set.Class
,手动强制它,但您将得到一条警告,这意味着您将负责确保它的安全。

请参阅由于类型擦除(类型参数由编译器删除);以下情况很好:
Class clazz=(Class)Set.class;
@Daniele,感谢您提供的解决方案。它可以工作,但会产生编译器警告。我正在尝试在没有警告的情况下找到解决方案。将对我的问题进行澄清。您可以安全地添加
@SuppressWarnings({“unchecked”,“rawtypes”})
。也许你可以看看这个问题:@SergeiTarasov:我看不到一个优雅的方法来抑制取消选中的类型。如果集合的初始化是由API的客户端完成的,也许你应该在你的端上添加一个额外的实现,它将在你的端上抑制类型转换,而不是client结束。。。。。
Class<Set<String>> clazz = Set<String>.class;