【问题标题】:Using @Override with a super interface将@Override 与超级接口一起使用
【发布时间】:2011-08-26 09:01:30
【问题描述】:

更新:过去,这只是 maven 的编译级别问题。

问题涉及@Override 注释和超级接口。

这很简单,因为它真正的问题是@Override 注释的范围不限于上层接口...

这里有一些简单的代码来理解这个问题:

public abstract interface CrudDao<T>
{
    void update(T bean);

    T get(Object... pk);

    void delete(Object ...pk);

    T create(T bean);
}



public interface BeanDao extends CrudDao<Bean>
{
    Bean moreSpecificGetMethod();
    void moreSpecificUpdateMethod();
}

public class BeanDaoImpl implements BeanDao {

    @Override
    public void update(Bean bean){}

    @Override
    public Bean get(Object... pk){}

    //... Rest of the methods 
}

编译器说方法应该在 BeanDao 接口中创建。为什么不从超级接口解析方法?

【问题讨论】:

  • 您确定是public interface BeanDaoImpl 而不是public class BeanDaoImpl
  • 对不起,当然不是公共接口BeanDaoImpl而是公共类BeanDaoImpl,更正一下。
  • 我正在使用最新的 1.6 JDK,并在 eclipse 中使用默认合规设置。
  • 现在BeanDaoImpl 是一个非抽象类,你不能有没有主体的方法......而且方法必须是public 是故意“简化”问题吗?跨度>
  • 如果您将 BeanDaoImpl 设为抽象并将方法设为公共,则相同的代码不会给出任何编译错误......它工作正常。

标签: java interface


【解决方案1】:

编译器和@Override 注解处理器都很好。在使用 javac 编译期间(在命令行上),针对 BeanDaoImpl 类的更新方法列出了以下消息:

info.example.BeanDaoImpl 中的update(info.example.Bean) 无法实现 info.example.CrudDao 中的更新(T);试图分配较弱的访问权限 特权;是公开的

原因是 CrudDao 中的update 方法实际上是公开的。根据Java Language Specification

接口主体中的每个方法声明都是隐式公开的。

在公开BeanDaoImpl.update 方法后,错误消息就会消失。这同样适用于来自其他方法的类似错误消息。

Eclipse项目设置也有问题。仅仅因为您使用的是JDK 1.6 运行Eclipse,你不需要自动让编译器不抱怨@Override注解处理。您需要在项目设置的Java Compiler 面板中将项目的Compiler compliance level 设置为1.6。值为 1.5 将导致 Eclipse 注释处理器抱怨未实现的方法,而事实上,您这些方法已实现,但在超级接口中声明,就像您的情况一样。

编译器合规级别设置的问题部分是由于最初的@Override specification - 它仅限于超类,并且不包括作为超类型的接口。这已在 Java 6 中修复,但 the documentation was not updated。编译器遵从级别 1.5 使 Eclipse 注释处理器将 @Override 注释方法视为需要存在于超类中而不是超类型中的方法。

【讨论】:

    【解决方案2】:

    公共接口 BeanDaoImpl 实现 BeanDao {

    @Override
    void update(Bean bean);
    
    @Override
    Bean get(Object... pk);
    
    //... Rest of the methods  }
    

    将工具更改为扩展。接口不实现它们扩展的其他接口。

    如果你这样做,你所指的错误就会消失。

    应该是:

    公共接口 BeanDaoImpl 扩展 BeanDao {

    @Override
    void update(Bean bean);
    
    @Override
    Bean get(Object... pk);
    
    //... Rest of the methods  }
    

    【讨论】:

    • BeanDaoImpl 是一个类而不是接口
    • 我很早就编辑了错误,我正在工作,只是复制粘贴了界面,对此感到抱歉。 IMPLEMENTATION 显然是接口的实现,并且是这样的。这两种方法都是公开的并且有正文。
    【解决方案3】:

    @Override Javadoc 状态。

    表示方法声明旨在覆盖方法 在超类中声明。如果一个方法用这个注释 注释类型但不覆盖超类方法,编译器 需要生成错误消息。

    在你的情况下,我们有一个问题:

    • 要么是您需要 extends 的接口(而不是 implements BeanDao 并删除 update/get 方法),要么
    • 它是一个类(不是抽象的),这意味着您 implements BeanDao 并实现被覆盖的方法。

    【讨论】:

      【解决方案4】:

      对您发布的代码的明显更正如下:

      public class BeanDaoImpl implements BeanDao {
          @Override
          public void update(Bean bean) {}
      
          @Override
          public Bean get(Object... pk) {
              return null;
          }
      }
      

      方法需要是公开的并且有一个主体。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-16
        • 1970-01-01
        • 1970-01-01
        • 2012-10-23
        • 2018-09-21
        • 2019-04-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多