是否可以编写Marker接口

我已经完成了以下教程:

http://www.javaworld.com/community/node/2915

在阅读完上面的文章之后,我觉得,编写Marker接口是不可能的,因为,如何指导编译器,它是什么标记,它嵌入到Marker接口的.class文件中。

如果我错了,请纠正我。 欢呼:)

这里的标签是六进制十进制代码AC ED,它被添加到实现Serializable接口的那个类的.class文件中。 因此,JVM以特殊方式处理此类文件(可能是一些繁重的资源分配工作),因为此类的实例可能是序列化的。 对于普通类,它会添加CA FE hex。

啊哈! 我理解你的困惑。

  • CA FE是字节码文件的幻数; 即编译类时获得的文件。 ANY类的字节码文件具有这个神奇的数字,无论它是可序列化的还是不可序列化的。

  • AC ED是序列化Java对象文件的神奇数字; 即您序列化某些可序列化类的实例的文件。

您正在混合两个不同的概念(类和实例)及其各自的表示。

所以你的问题的答案是……当然你可以编写自己的标记界面! 关于实现标记接口的类,编译器没有什么特别之处。

但是,在纯Java中复制Java对象反序列化的实现是不可能的。 对象反序列化使用后门( Unsafe.allocateInstance方法)来创建对象而不调用其构造函数。 AFAIK,此方法无法从普通的Java代码中调用。 (即使它可以,也不应该……)

当然你可以写一个标记界面。 标记接口通常只是一个完全没有方法的接口(所以任何类都可以实现它)。

你似乎认为标记界面有一些神奇的属性,可以自己做一些事情。 事实并非如此。 相反, 其他一些代码可以对某个对象上标记接口的存在作出反应,并在类实现时采取不同的行为。 但标记界面本身并没有做任何事情

 package com.example; interface MarkerInterface {} 

你有一个。 只需将其复制到com/example/MarkerInterface.java ,编译并使用它!

这是一个用法示例:

 class SomeClass implements MarkerInterface { // ... } 

您无法创建对JVM有意义的标记接口,就像java.io.Serializable接口那样。 但是,您可以使用instanceof创建一个您在自己的代码中检查的标记接口。

然而,由于我们有注释 ,因此通常不鼓励以这种方式使用标记接口。 使用注释处理工具(apt)在编译时以各种方式标记类方法和字段,或者在运行时使用reflection标记类的方法和字段是为其创建的注释。

因此,而不是像这样创建一个标记界面并使用它:

 class MyClass implements MyMarkerInterface { } 

你应该创建一个注释并像这样使用它:

 @MyAnnotation class MyClass { } 

取决于您对Marker界面的理解。 但一般来说,您可以在代码中使用instanceof来检查实例是否实现了Marker接口,然后对此实例执行某些操作…