Java:原始匿名类在其方法中丢失了泛型类型
Posted
技术标签:
【中文标题】Java:原始匿名类在其方法中丢失了泛型类型【英文标题】:Java: Raw anonymous class loses generic types in its methods 【发布时间】:2021-09-28 22:18:17 【问题描述】:Java 编译器的这种行为让我有点不知所措。有人可以解释为什么会这样吗?考虑这个例子:
public static abstract class GenericClass<A extends GenericClass<A>>
protected abstract void method();
protected <B> B getB(Class<B> bclass)
return null;
// ...
GenericClass<?> gc = new GenericClass()
@Override
protected void method()
String s = getB(String.class); // does not compile
;
String s = gc.getB(String.class); // compiles
由于new
中没有给出泛型参数,匿名类继承自原始类型GenericClass
。即使方法getB
没有提及A
,通用信息仍然丢失并且方法调用无法编译。为什么会这样?
此外,我无法为new
指定泛型参数的原因是因为它应该是匿名类本身,但我无法命名匿名类来传递它。我该如何正确地做到这一点?
【问题讨论】:
【参考方案1】:存在原始类型是为了与泛型存在之前的代码兼容。它们被视为对所有通用事物的完全“退出”。如果您想要泛型,请不要使用原始类型。这就是语言设计的意图。
这里的解决方案是给类命名。是的,类可以出现在方法和其他语句块中;这样的东西被称为本地类。匿名类基本上是一个没有名字的本地类——本地类可以做任何匿名类可以做的事情。
String thisIsFine()
var cell = new Object() String s; ; // example local variable to show local classes can access them
class GenericImpl extends GenericClass<GenericImpl>
@Override
protected void method()
cell.s = getB(String.class);
new GenericImpl().method();
return cell.s;
【讨论】:
本地课程可以解决问题,谢谢。虽然我不拥有实现 GenericClass 的代码,但我可以推荐这个解决方案。同时我仍然不太明白为什么原始类型会关闭 all 泛型,即使是那些不直接参与类类型定义的泛型。 @NebehrGudahtt 因为您通常不会在方法调用中指定泛型。预泛型代码可能包含GenericClass g = ...; g.getB(...)
之类的内容,并且在调用getB
时不会检查泛型。在泛型之后,调用g.getB
的语法不会改变,因为我们通常会保留推断的方法泛型。所以大多数时候语法不会向编译器发出信号,无论我们想要方法的原始类型还是泛型类型。因此,为了兼容性,调用的原始性必须选择与接收者的原始性相同。
但是为什么同样的调用在类方法之外起作用?
@NebehrGudahtt 因为接收者的类型不同。 GenericClass
是原始类型,为了兼容性,all 上的 all 泛型必须删除,但 GenericClass<?>
是普通泛型类型,具有“正确”类型为一切。以上是关于Java:原始匿名类在其方法中丢失了泛型类型的主要内容,如果未能解决你的问题,请参考以下文章
java基础总结 -- 泛型 在类接口方法匿名类元组等使用 堆栈例子 商店模型