在运行时忽略@Override on subclass中的方法“出现”

时间:2013-07-05 23:09:48

标签: java override

我真的希望我只是遗漏了一些简单的东西,但我正在阅读以下内容:http://docs.oracle.com/javase/tutorial/java/IandI/override.html

我有两个类和一个接口。字面意思是此Oracle文档页面中显示的“用例”。但是,当我运行JUnit测试时 - 只调用超类中的方法,并且该方法具有我不想调用的简单默认值:

界面包含此方法签名:

public interface RecordServiceInterface {
    List<String> searchRecords(String id) throws ServiceException;
}

实现接口的超类包含带有缺省值的此方法 - Eclipse IDE在找到实现类未实现的缺失方法时插入它。

public class RecordService implements RecordServiceInterface {
    public List<String> searchRecords(String id) throws ServiceException {
        // TODO Auto-generated method stub
        return null;
    }
}

在运行时,每次只调试调试器时调用上面的内容。

子类然后扩展超类并具有想要覆盖的真实实现:

public class MyRecordService extends RecordService {
    @Override
    public List<String> searchRecords(String id) throws ServiceException {  
        List<String> myList = new ArrayList<String>();

        // ...

        return myList;
    }
}

我必须完全忽视@Override的观点。在执行期间,它反复无法使用@Override注释进入方法。

4 个答案:

答案 0 :(得分:2)

@Override注释所做的全部是,如果类继承中的任何地方都没有可以覆盖的对应方法,则编译器会生成错误。因此,它旨在确保您的重写方法实际上覆盖了某些内容。

如果没有调用MyRecordService中的方法,而是调用RecordService类中的方法,那么我猜测错误的对象是实例化的。所以你面前的是RecordService类型的对象,而不是MyRecordService类型的对象。

由于你没有提供这部分代码,这只是一个猜测,基于你的继承看起来很好。

答案 1 :(得分:0)

@Override是一个编译时注释,用于验证带注释的方法是否实际覆盖了超类/接口中的某些内容。它不会影响运行时行为。

发布测试代码,以便我们更清楚地了解您要做的事情。

答案 2 :(得分:0)

正如您在@Override javadoc中所看到的,@Override的保留政策是来源。换句话说:它在编译时使用,但不会生成二进制代码(类文件)。

特别是,SOURCE保留政策为defined

  

编译器将丢弃注释。

答案 3 :(得分:0)

@Override实际上只是一种在尝试覆盖super class'或instance方法时捕获拼写错误的方法,以及偶尔尝试覆盖final的方法方法(按设计不可覆盖)。

当选择要调用的内容时,覆盖行为可以实现覆盖方法的覆盖方法。

例如:

RecordServiceInterface service = new RecordService();
RecordService service2 = new RecordService();

同时使用serviceservice2,将调用RecordService的实施。现在考虑:

RecordServiceInterface service3 = new MyRecordService();
RecordService service4 = new MyRecordService();
MyRecordService service5 = new MyRecordService();

使用service3service4service5,将调用MyRecordService的实施。

覆盖不会替换父类型的方法,除非它是链的一部分(例如,在最后一个块35中创建的所有三个实例)。如果Object的实例不是类型(在这种情况下为MyRecordService),则不会为该实例的行为覆盖该方法。 serviceservice2仍然会调用RecordService的实施。

另一个例子可能更清楚:

public interface Runnable {
    void run();
}

public class RunnableA implements Runnable {
    @Override
    public void run() { System.out.println("A"); }
}

public class RunnableB extends RunnableA {
    @Override
    public void run() { System.out.println("B"); }
}

public class RunnableC implements Runnable {
    @Override
    public void run() { System.out.println("C"); }
}

您只能拥有其中任何一个的实例,因此每次调用instance.run()时只会输出一行。它取决于实例的实现,而不是类路径中存在的内容。