在Java中,@Override是用来做什么的?

18
public class Animal {
   public void eat() { System.out.println("I eat like a generic Animal."); }

}

public class Wolf extends Animal {
   @Override
   public void eat() { System.out.println("I eat like a wolf!"); }
}

@Override 实际上是否具有功能或只是一种注释?


重复:https://dev59.com/4HVD5IYBdhLWcg3wGHau - Jørn Schou-Rode
6个回答

28

这段内容来自于Java教程中的注解章节:

@Override——@Override注解 告诉编译器该元素意在覆盖超类中已声明的元素(覆盖方法将在"接口和继承"一课中讨论)。

   // mark method as a superclass method
   // that has been overridden
   @Override 
   int overriddenMethod() { }

尽管覆盖一个方法时不一定需要使用此注解,但使用它有助于防止出错。如果标记了@Override的方法未能正确地覆盖其中一个超类中的方法,则编译器会生成错误。

让我们看看在Java语言规范中给出的示例 9.6.1.4 Override。假设您想要覆盖一个方法,比如equals,但是写成了:

    public boolean equals(Foo that) { ... }

改为:

    public boolean equals(Object that) { ... }

虽然这段代码是合法的,但是如果在equals方法声明中注释上@Override将会导致编译时错误,因为你实际上并没有覆盖该方法,而是重载了它。这可能会引起严重的错误,使用Override注解类型有助于及早检测到这些问题。


1
正确。在构建时间之后,它不会影响任何东西。 - Marc W
注释(Annotation)是否区分大小写? - symfony
1
@symfony 是的,注释是一种类型。 - Pascal Thivent

10

Override注解是一种编译时注解,如果带有该注解的方法实际上没有覆盖父类方法,Java编译器会抛出错误。

您可以尝试将Wolf类更改为不扩展Animal类,如果存在Override注解,则会显示编译时错误。


1
@symfony 不是在上面的代码中。但是如果你将eat拼错为eats并且没有使用@override,那么编译器会认为你正在创建一个新方法,并且会编译成功而没有任何警告。它允许编译器找到错误。更常见的是,它帮助开发人员找到在方法参数中使用了错误类型的错误,例如执行public boolean equals(MyObject o)而不是public boolean equals(Object o) - user120587
最后,它是区分大小写的吗?我看到你写的是@override而不是@Override。 - symfony
是的,它是区分大小写的。那只是我评论中的一个笔误。仍在等待SO将编译器检查添加到评论部分。 :) - user120587

1

0

@Override既可以作为注释,也可以作为断言,表明您确实正在覆盖某些内容。如果您使用了@Override,但实际上并没有覆盖任何内容,编译器将生成一个错误。有关更多详细信息,请参阅文档页面


0
如果你从父类中删除了“eat”方法,或者在子类中将其拼写错误为“eats”,那么你的代码现在将无法编译。如果没有使用“@Override”注释,你可以做任何一种方式,你的代码仍然可以编译,但它不会做你想要的事情(即覆盖一个方法)。

0

它在运行时不执行任何操作,但可以帮助您捕获错误:

如果您认为自己将要覆盖一个方法,但由于拼写问题或参数类型而没有覆盖(如果没有注释),则代码将编译为无用的东西(例如:您的方法不会被调用,但是你意外地未覆盖的超类方法会被调用)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接