我有以下指定的行为。
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到抽象类/接口,则会清除此错误。
我不明白为什么会导致错误以及为什么添加这些方法/类型可以修复它。不知道我在这里缺少什么。
这是设计使然,并在JLS \xc2\xa715.9.5中指定:
\n\n\n如果带有 a 的类实例创建表达式使用
\nClassBody菱形 (<>) 作为要实例化的类的类型参数,则对于 中声明的所有非私有方法ClassBody,就好像该方法声明被注释为@Override。
您的公共getValue方法不会覆盖超类中的任何内容,因此由于隐式添加的@Override.
这样做的理由是:
\n\n\n当
\n<>使用 时,推断的类型参数可能与程序员预期的不同。因此,匿名类的超类型可能与预期不同,并且匿名类中声明的方法可能不会按预期覆盖超类型方法。将此类方法视为带有注释@Override(如果它们没有显式注释@Override)有助于避免无提示的错误程序。
我对此的解释是,当您在匿名类中声明公共方法时,它很可能会覆盖某个方法,因此@Override当您使用<>. 这是为了确保您编写的方法确实覆盖超类中的方法,因为如果不显式写下类型参数,编译器可能会推断出意外的类型,并且您编写的签名实际上不会覆盖超类中的方法。(遗憾的是,我想不出一个很好的例子)
很少需要在匿名类中声明公共方法而不进行覆盖。如果您想声明一个方法,只需将其声明为私有方法 - 无论如何您都无法从外部调用它,除非您将表达式分配new给var,而这种情况非常罕见。
| 归档时间: |
|
| 查看次数: |
120 次 |
| 最近记录: |