定义: |
---|
Java中的标记接口是一个空接口,没有任何方法,字段或常量。 有时也称为标记接口。 |
那么为什么使用Marker接口呢?
有效的问题! 它没有解决与定义实现该接口的类的协定的接口的目的。 这些接口定义了没有实现的方法,因为它们告诉子类需要做什么,但是由子类决定如何实现此方法。 但是,在Marker接口的情况下,没有成员。
标记接口是一种声明有关类的元数据的方法。 它告诉JVM,需要以不同的方式对实现标记器接口的类的对象进行特殊处理。 Java API中定义了一些现成的Marker接口:
java.io.Serializable
java.lang.Cloneable java.util.RandomAccess java.util.EventListener 我们还可以像创建其他接口一样创建自己的标记接口版本。
让我们更深入地了解Cloneable接口。 当需要在Java中克隆对象时,我们使用Object的clone()方法。 但是请注意,此方法不是Cloneable接口的一部分,即,当您的类默认实现Cloneable接口时,将不会像其他任何标准接口一样实现clone方法。 当我们显式定义它或调用对象的clone方法时,就可以完成此操作。
因此,不可能仅凭借对象实现此接口的事实来克隆对象。 即使克隆方法是反射式调用的,也不能保证它会成功。
public Object clone() {Object clone = null;try {clone = super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return clone;
}
这里的一个关键点是,当您尝试使用clone()方法克隆对象时,除非实现Cloneable接口,否则将获得CloneNotSupportedException 。 JVM非常聪明–是吗?
注意事项:
如前所述,除了使用内置的标记接口之外,我们还可以创建特定于应用程序的标记接口,因为这是标记和逻辑分类代码的一种好方法。 这在尝试创建框架或开发API时主要有用。
有趣的一点:
Runnable不是Marker接口。 尽管run是对JVM启动方法的特殊指令,但是Runnable不是标记接口,因为Runnable内部具有公共的void run()方法。
标记界面存在问题:
标记接口的主要问题是接口定义了用于实现类的协定,并且该协定被所有子类继承。 这意味着您不能取消实施标记。 如果创建不想序列化的子类(可能是因为它依赖于瞬时状态),则必须诉诸显式抛出NotSerializableException .
现在让我们回到重点。 使用注释比标记界面更好吗?
为了回答这个问题,让我们更详细地研究Java注释。
定义: |
---|
Java注释是Java 1.5中引入的语法元数据(关于数据的数据)的特殊形式。 像Java类一样,接口甚至注释都可以在多个Java元素上使用。 |
与Javadocs不同,Annotations具有更多功能,可帮助在运行时进行处理。 注释用于程序包或类声明,方法声明,字段声明和变量声明中。 它减少了编码工作,让开发人员可以轻松开发,专注于业务逻辑,从而提高了自动化程度。
注释与标准Java元素之间用“ @”符号分隔。 每当编译器遇到带有任何Java元素的这些注释时,它都会从注释中提取信息并自动生成代码。
注释的用途:
- 将信息传递给编译器–用于检测错误或抑制警告。 例如@ SuppressWarnings,@不建议使用
- 编译时间和部署时间处理–几种工具可以处理注释信息以生成代码XML文件等。诸如Spring,Hibernate之类的框架大量使用注释。
- 运行时处理–仅在运行时处理这些批注。
以标记接口的类似方式,我们也有标记注释。 标记注释没有任何方法或元素。 该行为与Marker接口相同。
例如, @ Override是内置的Java Marker批注类型,可以将其实现为方法,以指示编译器编译器该方法将覆盖超类中的方法。 它不包含任何其他程序元素。 如果您在不覆盖超类方法的方法上使用此批注,则编译器将发出编译错误,以提醒您该事实。 这种注释类型可以防止程序员在重写方法时犯错误,因为开发人员很可能实际上会在超类中重载方法而不是重写。
似乎批注比标记界面更好,因为批注可以达到相同的效果。
- 它可以标记变量,方法和/或类。
- 它可以专门标记任何类,也可以通过继承标记。 标记接口将标记已标记类的所有子类。 例如,如果我们必须将一个类标记为不可序列化,则必须专门将其标记为瞬态。 这可能是值得商bat的,因为注释不是不可子类化的,可能是优点还是缺点。 注释默认情况下不会继承– isAnnotationPresent()会告诉您该特定类上是否存在该注释,而不是它是否存在于超类或超接口上。 因此,如果您作为批注旨在提供的特殊功能的实现者,希望批注的行为像继承一样,则不仅要检查此类 ,还要检查每个超类和每个超接口的isAnnotationPresent() 。
- 您可以将数据添加到标记中。 换句话说,非空白的注释具有价值,因为您所标记的不仅仅是类型。
因此,他们每个人都有一定的优点和缺点,我个人认为应该由开发人员来决定是否使用标记界面或标记注释,因为他们必须决定考虑实际情况并判断优点和缺点。他们两个,并确定最适合该要求的。
参考: 是否有更好的Marker方法? 从我们的JCG合作伙伴 Mainak Goswami在Idiotechie博客上获得。
标记 2012-10-30
翻译自: https://www.javacodegeeks.com/2012/10/is-there-a-better-approach-to-marker.html