Java:原始匿名 class 在其方法中丢失了通用类型

Java: Raw anonymous class loses generic types in its methods

我对 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 中没有给出通用参数,所以匿名 class 继承自原始类型 GenericClass。即使方法 getB 没有提到 A,通用信息仍然会丢失,并且方法调用不会编译。为什么会这样?

此外,我无法为 new 指定通用参数的原因是因为它应该是匿名 class 本身,但我无法将匿名 class 命名为交上来。我该如何正确执行此操作?

原始类型的存在是为了与泛型存在之前的代码兼容。他们被视为对所有通用事物的完全“选择退出”。如果你想要泛型,不要使用原始类型。这就是语言设计的意图。

这里的解决方法是命名class。是的,classes 可以出现在方法和其他语句块中;这样的东西叫做本地classes。匿名 class 基本上是没有名字的本地 class — 本地 classes 可以做任何匿名 classes 可以做的事情。

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