Java 如果标记接口没有任何方法,它是如何工作的?

Java 如果标记接口没有任何方法,它是如何工作的?,java,interface,Java,Interface,我知道什么是标记接口以及何时需要使用它。有一个问题我还不清楚。如果一个标记接口没有任何方法或主体,那么它在运行时是如何工作的?一个标记接口本身就不能“工作”。顾名思义,它只是将类标记为特定类型。其他一些代码必须检查标记是否存在,并根据该信息执行某些操作 如今,注释通常执行与标记接口以前相同的角色。使用它唯一有用的方法是 if (instance instanceof MyMarkerInterface) { ... } 标记接口可以在许多地方替换为注释,但是标记接口仍然可以用于 编译时

我知道什么是标记接口以及何时需要使用它。有一个问题我还不清楚。如果一个标记接口没有任何方法或主体,那么它在运行时是如何工作的?

一个标记接口本身就不能“工作”。顾名思义,它只是将类标记为特定类型。其他一些代码必须检查标记是否存在,并根据该信息执行某些操作


如今,注释通常执行与标记接口以前相同的角色。

使用它唯一有用的方法是

if (instance instanceof MyMarkerInterface) {
   ...
}

标记接口可以在许多地方替换为注释,但是标记接口仍然可以用于

  • 编译时检查。您可以有一个方法,该方法必须接受具有给定标记接口的类的对象,例如

不能单独使用注释进行编译时检查

顺便说一句:使用泛型可以有两个接口,但是好的例子很少

  • 支持依赖接口识别组件类型的框架。像OSGi
编辑:我将其用于侦听器标记接口。侦听器具有标记有注释的方法,但这些方法可以具有任何名称或类型。它将编译器时间检查添加到一个纯粹的运行时链接中

public Component implements Listener {

@ListenerCallback
public void onEventOne(EventOne... eventOneBatch) { }

@ListenerCallback
public void onEventTwo(EventTwo eventTwo) { }
}

marker接口告诉JVM,被marker接口标记的类将添加marker接口的功能。与实现Cloneable类似,它告诉JVM这个类实现了Cloneable,因此JVM必须逐位复制它。

Java中的Marker接口是没有字段或方法的接口,或者简单地说,Java中的empty接口称为Marker接口。e、 g.可序列化、可克隆和远程接口。它们用于向编译器或JVM指示信号或命令。它还可以用于对代码进行分类。您还可以编写自己的标记接口,并使用它们对代码进行逻辑划分。此外,您还可以在这些类上编写任何预处理操作

嗨,丹,如果我的理解有误,请纠正我。正如名称所说的“marker”,这是否意味着一旦任何类实现了marker接口,JVM就会在运行时使用某种机制将该类标识为已标记,以实现类似cloneable的接口。@Dan,因为您告诉过
“其他一些代码必须检查标记是否存在,并根据这些信息执行某些操作。“
,您能否提供一个相同的示例/场景,@Kamal No,标记接口对JVM没有特殊意义,并且本身不会产生额外的功能。在可克隆的情况下,它只是告诉其他代码,这个类的开发人员保证实例是可正确克隆的。Cloneable可以说是标记接口被误用的一个很好的例子。接口应该真正执行公共克隆方法的规定。@Deepak我现在想不出一个好的例子,我不会写其他不涉及标记接口的例子。标记接口并没有那么有用(它们没有mklhmnn演示的那么多)。对
Cloneable
Serializable
的讨论是误导性的,因为实际的克隆和序列化机制并不真正依赖于标记接口用于指示哪些类可以被克隆或序列化这一事实。回滚了对这一点的编辑,因为它完全改变了答案,并且不是很有效我认为这很清楚。一般来说,我不介意编辑,但如果你想要一个完全不同的答案,请添加你自己的答案,而不是更改我的答案,因为我的名字仍然列在上面。你的
myMethod
或多或少是无用的,因为标记接口没有比
Object
更多的方法。查看
java.lang.Cloneable
java.util.RandomAccess
的文档中的“好”示例(就像我在引入注释之前这样做一样好)。@Feuermurmel我不认为Cloneable是标记接口的好示例,因为不清楚为什么它没有
公共对象克隆()
方法。@MikeL。我也不喜欢在Java中实现克隆的方式,但是如果
Cloneable
声明了这样一种方法,那么如果请求浅拷贝,类如何从自动克隆中获益呢?我将投票从
Cloneable
更改为
java.rmi.Remote
public Component implements Listener {

@ListenerCallback
public void onEventOne(EventOne... eventOneBatch) { }

@ListenerCallback
public void onEventTwo(EventTwo eventTwo) { }
}