由于非私有方法无法重写或实现超类型的方法,因此无法使用“<>”

rgb*_*k21 5 java generics

我有以下指定的行为。

interface ValueEditorPopupView<T> {
  void setValue(T value);

  void setApplyEnabled();
}

abstract class ValueEditorPopup<T> implements ValueEditorPopupView<T> {
  @Override
  public void setApplyEnabled() {
    System.out.println("In ValueEditorPopup.setApplyEnabled()");
  }
}

class ListEditorTextField {
  private final ValueEditorPopup<String> popup;

  ListEditorTextField() {
    popup = new ValueEditorPopup<>() {
      @Override
      public void setValue(String value) {
        System.out.println("In Anonymous Class impl setValue()");
      }

      // When I add a method that is NOT defined in the abstract class/interface
      // I get an error for using the diamond operator in the class declaration above
      // "Cannot use '<>' due to non-private method which 
      // doesn't override or implement a method from a supertype"
      // This error clears if I explicitly specify `new ValueEditorPopup<String>(){}`
      // in the anonymous class instantiation or 
      // add `getValues` to the abstract class/interface.
      public void getValues() {}
    };
  }

}
Run Code Online (Sandbox Code Playgroud)

正如上面代码中的注释所述,当我添加一个未在抽象类/接口中定义的方法时,我会因在上面的类声明中使用菱形运算符而收到错误:

“由于非私有方法无法重写或实现超类型的方法,因此无法使用‘<>’”

new ValueEditorPopup<String>(){}如果我在匿名类实例化中显式指定或添加getValues到抽象类/接口,则会清除此错误。

我不明白为什么会导致错误以及为什么添加这些方法/类型可以修复它。不知道我在这里缺少什么。

Swe*_*per 6

这是设计使然,并在JLS \xc2\xa715.9.5中指定

\n
\n

如果带有 a 的类实例创建表达式使用ClassBody菱形 ( <>) 作为要实例化的类的类型参数,则对于 中声明的所有非私有方法ClassBody,就好像该方法声明被注释为@Override

\n
\n

您的公共getValue方法不会覆盖超类中的任何内容,因此由于隐式添加的@Override.

\n

这样做的理由是:

\n
\n

<>使用 时,推断的类型参数可能与程序员预期的不同。因此,匿名类的超类型可能与预期不同,并且匿名类中声明的方法可能不会按预期覆盖超类型方法。将此类方法视为带有注释@Override(如果它们没有显式注释@Override)有助于避免无提示的错误程序。

\n
\n

我对此的解释是,当您在匿名类中声明公共方法时,它很可能会覆盖某个方法,因此@Override当您使用<>. 这是为了确保您编写的方法确实覆盖超类中的方法,因为如果不显式写下类型参数,编译器可能会推断出意外的类型,并且您编写的签名实际上不会覆盖超类中的方法。(遗憾的是,我想不出一个很好的例子)

\n

很少需要在匿名类中声明公共方法而不进行覆盖。如果您想声明一个方法,只需将其声明为私有方法 - 无论如何您都无法从外部调用它,除非您将表达式分配newvar,而这种情况非常罕见。

\n