Java中interface和@interface有什么区别?

418

我自大学时期使用JBuilder以来就没有接触过Java,所以有些陌生-无论如何,本周我一直在开发一个小型Java项目,并且使用Intellij IDEA作为我的IDE,这是与我的常规.Net开发不同的变化。

我注意到它支持添加接口和@interfaces,什么是@interface,它与普通接口有什么区别?

public interface Test {
}

vs.

对比。

public @interface Test {
}

我进行了一些搜索,但没找到太多有用的信息涉及@interface。

6个回答

413

@符号表示注解类型定义。

这意味着它不是一个界面,而是一个新的注解类型 - 用作函数修饰符,例如@override

请参阅有关此主题的Javadocs条目


18
非常感谢,知道了就好。那么,为什么叫它@interface,而不是@annotation呢?我在想,这似乎是一个不必要的负担重重的术语。 - Bittercoder
10
教程和JLS提到,注解是一种特殊类型的接口。关于这个主题,似乎没有太多的讨论,但是http://javarunner.blogspot.com/2005/01/annotations-in-java-15.html解释了注解是Annotation接口的隐式扩展,并且@和interface结合使用以区分普通接口。您可能还想阅读有关注解的JSR规范。 - DavidValeri
3
文档确实提到了:“关键字interface前面要加上at符号(@) (@代表注释类型)”。这是我在命名方面能找到的全部理由。 - Shaishav
实际上,Bittercoder的问题是非常必然的,而DavidValeri的链接非常好地解释了它。因此,你可以这样写:@interface,而不仅仅是@ interface - starriet
1
Kotlin 通过称其为“注解”而不是重载术语“接口”,使其更好。 - EternalObserver
我也是一样的情况——这似乎是Java中的C#属性的等价物。(将其作为评论添加以便搜索,但在评论之前并未完全比较!) - undefined

154

接口:

通常情况下,接口公开了一个契约,但没有暴露其底层实现细节。在面向对象编程中,接口定义了抽象类型,公开了行为,但不包含任何逻辑。实现由实现接口的类或类型定义。

@interface:(注释类型)

以下面的例子为例,有很多注释:

public class Generation3List extends Generation2List {

   // Author: John Doe
   // Date: 3/17/2002
   // Current revision: 6
   // Last modified: 4/12/2004
   // By: Jane Doe
   // Reviewers: Alice, Bill, Cindy

   // class code goes here

}

你可以声明一个注解类型,而不是这样做。

 @interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}

然后可以将其作为以下类的注释:

@ClassPreamble (
   author = "John Doe",
   date = "3/17/2002",
   currentRevision = 6,
   lastModified = "4/12/2004",
   lastModifiedBy = "Jane Doe",
   // Note array notation
   reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {

// class code goes here

}

提示: 在代码中,许多注释被替换为注解。

参考:http://docs.oracle.com/javase/tutorial/java/annotations/declaring.html


6
确实有用。我不知道Java可以做到这一点。 - Jay Sidri
先前的答案包括了这个链接,这是这些信息的来源。我发现它很有用,可以找到更多关于这个主题的信息。 https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html - PatS
4
我不确定为什么每个人都喜欢这个答案,因为它只给出了注解的非常有限的用例。在Java中,注解的用途远不止取代注释。注解的强大之处在于它们可以更改带注解的元素在运行时的行为或处理方式。 - Leonid Usov
@LeonidUsov,请您能否给一个例子呢?我是Java和基于JVM的语言的新手。就我所看到的,它们似乎实现了装饰者设计模式。这是全部还是我错过了一些注释所提供的功能? - EternalObserver
1
@EternalObserver 不,它们不是装饰器设计模式,因为它们不直接改变注释实体在运行时的行为。这就像是一个元数据片段,你可以附加到你的代码元素上,编译器后续可以使用它来改变其行为或者在运行时由专用代码查询。一个常见的例子是 @Serialize-related 注释集合,它们可以改变给定类如何打包成流或解包。 - Leonid Usov
@LeonidUsov 谢谢,Python和JS中@符号用于装饰器。所以我很困惑。现在我明白了,注释只用于附加元数据,而由框架决定如何利用元数据。 - EternalObserver

38
interface 关键字表示您正在声明一个传统的 Java 接口类。
@interface 关键字用于声明新的注释类型。

请参阅 oracle 文档教程 了解语法说明。
如果您真的想深入了解 @interface 的含义,请查看JLS

26

接口:定义实现它的类必须遵守的契约。

@接口:定义注解的契约。


16

接口是Java编程语言中用于指定类必须实现的行为的抽象类型,类似于协议。接口是使用interface关键字声明的。

@interface用于创建您自己的(自定义)Java注释。注释与Java类或接口一样在其自己的文件中定义。以下是自定义Java注释的示例:

@interface MyAnnotation {

    String   value();

    String   name();
    int      age();
    String[] newNames();

}

这个例子定义了一个名为MyAnnotation的注释类型并包含四个元素。注意@interface关键字,它告诉Java编译器这是一个Java注释定义。

注意每个元素的定义方式类似于接口中方法的定义。它有一个数据类型和一个名称。你可以使用所有基本数据类型作为元素数据类型。你也可以使用数组作为数据类型。但是不能使用复杂对象作为数据类型。

要使用上述注释,你可以像这样使用代码:

@MyAnnotation(
    value="123",
    name="Jakob",
    age=37,
    newNames={"Jenkov", "Peterson"}
)
public class MyClass {


}

参考资料 - http://tutorials.jenkov.com/java/annotations.html


0

使用 @interface 可以定义注解,而使用 interface 可以定义接口。

根据 Oracle 文档:“注解不直接影响程序语义,但它们会影响工具和库对程序的处理方式,进而影响运行程序的语义。注解可以从源文件、类文件或在运行时通过反射读取。”

注解通常有两个主要用途:它们有助于定义编程合同(例如 @Nonnull 注解),这意味着它们实际上什么也不做,但可以帮助程序员和 IDE 检测潜在的错误代码;还有运行时注解,通常由框架用于配置(例如 spring 中的 @Service 注解):核心检测您范围内带有特定注解的类并对其应用逻辑(任何您能想到的示例,如定义 Java 服务器、创建单例等)。

一般来说,一个初级程序员在进行一些基本的正常操作时,很少需要定义注解,但是如果他们的语言允许,定义和使用接口是任何新开发人员都应该学习的基础知识:通常建议在代码中使用接口以提高可维护性。

在我的个人经验中,自从我学习Java的那一天起,我就一直在定义和使用Java接口,但是直到我职业生涯的第5-6年,我才需要定义一个注释(使用现有注释进行标记是另一回事),而且这是一个非常具体的项目,一个代码自动生成器,类似于Lombok,但更为特定的客户端。
我想这取决于你工作的性质,但是今天,我无法计算我定义了多少接口,但是注释可以用双手的手指数来计算。我敢打赌,Java开发人员有很大的机会在整个职业生涯中都不需要定义一个单独的接口(除非您使用Swagger的基于注释的文档生成)。

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