Java 中的 Marker Interfaces?

2022-08-31 07:54:54

我被教导说,Java中的Marker接口是一个空接口,用于向编译器或JVM发出信号,表明实现此接口的类的对象必须以特殊方式处理,如序列化,克隆等。

但最近我了解到它实际上与编译器或JVM无关。例如,在接口的情况下,的方法会做一些事情来检测类是否相应地实现和抛出。一切都在代码中处理,这似乎是一个设计模式,所以我认为我们可以定义自己的标记接口。SerializablewriteObject(Object)ObjectOutputStreaminstanceOf SerializableSerializableNotSerializableException

现在我的怀疑:

  1. 上面第一点中提到的标记接口的定义是否错误?那么,我们如何定义一个标记接口呢?

  2. 而不是使用运算符,为什么方法不能像编译时类型检查而不是运行时那样?instanceOfwriteObject(Serializable)

  3. 注释如何比标记接口更好?


答案 1
  1. 上面第一点中提到的标记接口的定义是否错误?- 在部分是正确的,(1)标记接口必须是空的,(2)实现它意味着对实现类的某种特殊处理。不正确的部分是它暗示JVM或编译器将以不同的方式对待该类的对象:您正确地观察到Java类库的代码将这些对象视为可克隆,可序列化等。它与编译器或 JVM 无关。
  2. 而不是使用 instanceOf 运算符,为什么该方法不能像 writeObject(Serializable) 那样,以便进行编译时类型检查 - 这可以避免在需要“plain”时用标记接口的名称污染代码。例如,如果您创建一个需要可序列化的类,并且具有对象成员,则将被迫在编译时执行强制转换或创建对象。这很不方便,因为该接口没有任何功能。ObjectSerializable
  3. 注释如何比标记接口更好?- 它们允许您实现将有关类的元数据传达给其使用者的相同目的,而无需为其创建单独的类型。注释也更强大,允许程序员将更复杂的信息传递给“消费”它的类。

答案 2

不可能强制实施 on,因为不可序列化类的子类可以是可序列化的,但它们的实例可能会被上演回父类。因此,保留对不可序列化(如 )的内容的引用并不意味着引用的实例不能真正序列化。例如SerializablewriteObjectObject

   Object x = "abc";
   if (x instanceof Serializable) {
   }

父类 () 不可序列化,将使用其无参数构造函数进行初始化。、 引用的值是可序列化的,条件语句将运行。ObjectxString


推荐