Java 从泛型创建类对象

Java 从泛型创建类对象,java,class,generics,downcast,Java,Class,Generics,Downcast,在泛型方法中,我似乎无法在运行时访问该方法的泛型类型(错误:无法从类型变量中选择) 公共 在那里,解决这个问题的想法是在构造函数中提供一个类对象,并使用这个变量检查它是否可赋值。这似乎是一个相当愚蠢的解决方案,因为你可以把任何类放在那里,所有漂亮的类型检查都是无用的 所以,同样的问题是:当运行时的类型是众所周知的,为什么要在构造函数中提供.class?如何访问的实际类型 找到了一个非常丑陋的解决方案: public <A> A get(Animal a, Class<A>

在泛型方法中,我似乎无法在运行时访问该方法的泛型类型(错误:无法从类型变量中选择)

公共

在那里,解决这个问题的想法是在构造函数中提供一个类对象,并使用这个变量检查它是否可赋值。这似乎是一个相当愚蠢的解决方案,因为你可以把任何类放在那里,所有漂亮的类型检查都是无用的

所以,同样的问题是:当运行时
的类型是众所周知的,为什么要在构造函数中提供
.class
?如何访问
的实际类型


找到了一个非常丑陋的解决方案:

public <A> A get(Animal a, Class<A> clazz) {
    // same as above...
}
public A get(动物A,类clazz){
//同上。。。
}
因此,现在您必须提供一个
,但您可以在此处插入的唯一有效类是返回类型。但至少现在它是类型安全的


完全不方便…

与您的断言相反,运行时不知道A的类型。更多详情,请查看相关文件


简单地说,运行库知道您有一个类型为
的对象。但是,如果您不明确提供信息,它就无法区分
Whatever
Whatever
。这就是为什么建议您提供一个类对象。注意,这与编译阶段不同,在编译阶段中,完整的类型信息是已知的。

与您的断言相反,在运行时,A的类型是未知的。更多详情,请查看相关文件


简单地说,运行库知道您有一个类型为
的对象。但是,如果您不明确提供信息,它就无法区分
Whatever
Whatever
。这就是为什么建议您提供一个类对象。注意,这与编译阶段不同,在编译阶段中,完整的类型信息是已知的。

在运行时无法选择泛型类型


有关可能的解决方案,请参见此处:

无法在运行时选择泛型类型


请参见此处以获取可能的解决方案:

如果执行
instanceOfA.toString()
,会发生什么情况?它仍然会调用正确的方法等。只是缺少泛型信息,仍然非常无用,因为我必须将类型声明为参数,但是调用者不一定要给出实际的返回类型作为参数,因此类型安全性不存在……实际上,我甚至不理解这样的解释:当然,
任何对象在编译时都会被擦除,但这是一种通用方法,需要返回的类型在运行时必须是已知的,或者JVM无法正确地转换内容。对于
Dog d=get(a),我知道返回类型必须是
Dog
,而不是其他,这就是它在赋值中的声明方式。“我错过了什么?”克拉曼:打电话的人当然知道。但是被调用的方法不知道。它们是不同的,在运行时,调用的是同一个方法,不管调用方是否知道它在对狗或猫进行操作。如果执行
instanceOfA.toString()
,会发生什么情况?它仍然会调用正确的方法等。丢失的只是泛型信息,仍然非常无用,因为我必须将类型声明为参数,但是调用者不一定要给出实际的返回类型作为参数,因此类型安全性不存在……实际上,我甚至不理解这样的解释:当然,
任何对象在编译时都会被擦除,但这是一种通用方法,需要返回的类型在运行时必须是已知的,或者JVM无法正确地转换内容。对于
Dog d=get(a),我知道返回类型必须是
Dog
,而不是其他,这就是它在赋值中的声明方式。“我错过了什么?”克拉曼:打电话的人当然知道。但是被调用的方法不知道。它们是不同的,在运行时,调用的方法是相同的,不管调用方是否知道它在对狗或猫进行操作。
Animal a = new Dog();
Dog d = get(a);    // <- OK
Cat c = get(a)     // <- incompatible types, caught by else block
public <A> A get(Animal a, Class<A> clazz) {
    // same as above...
}