我有下面指定的行为.

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() {}
    };
  }

}

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

"无法使用"&lt;&gt;",因为非私有方法不重写或

如果我在匿名类实例化中显式指定new ValueEditorPopup<String>(){},或者在抽象类/接口中添加getValues,那么这个错误就会清除.

我不明白为什么会出现这个错误,为什么添加这些方法/类型可以修复它.我不确定我错过了什么.

推荐答案

这是根据设计,并在JLS §15.9.5中规定:

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

您的public getValue方法不会覆盖超类中的任何内容,因此由于隐式添加了@Override,因此出现了一个错误.

理由是:

当使用<>时,推断的类型参数可能不像程序员预期的那样.因此,匿名类的超类型可能不像预期的那样,并且在匿名类中声明的方法可能不会按预期重写超类型方法.将这些方法视为用@Override注释(如果它们没有用@Override显式注释)有助于避免错误的程序.

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

很少需要在匿名类中声明公共方法而不重写.如果想声明一个方法,只需将其声明为私有方法——除非将new表达式指定给var,否则无论如何都不能从外部调用它,这是非常罕见的.

Java相关问答推荐

try Dockerize Maven应用程序,但发布版本21不支持"

Javascript在边界中心调整ImageView大小

在AnyLogic中增加变量计数

即使我正在使用并发方法,使用Javascript的应用程序也会继续冻结'

使用联接和分页的SpringBoot Spring数据JPA

使用Room Database删除Jetpack合成中的所有项目后,UI未重新合成

在Eclipse中数组的可空性

将Spring Boot 3.2.0升级到3.2.1后查询执行错误

如何在我的世界中为互动增加冷却时间?

为什么有两种实现来检索数组类的组件类型?

如何在JUNIT测试中覆盖ExecutorService?

将关闭拍卖的TimerService

使用SWIG将C++自定义单元类型转换为基本Java类型

有没有办法知道在合并中执行了什么操作?

嘲笑黄瓜中的对象

TinyDB问题,无法解析符号';上下文&

为什么使用lo索引来解决二进制搜索问题不同于使用hi索引?

无限递归Java问题

Intellij 2023 IDE:始终在顶部显示菜单栏

具有 DayOfWeek 列表的 JPA 实体