java JVM 如何处理标记接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7791802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:28:05  来源:igfitidea点击:

How Marker Interface is handled by JVM

javajvm

提问by srini

Marker interface doesn't has any thing. It contains only interface declarations, then how it is handled by the JVM for the classes which implements this marker interface?

标记界面没有任何东西。它只包含接口声明,那么 JVM 如何为实现此标记接口的类处理它?

Can we create any new marker interfaces ?

我们可以创建任何新的标记界面吗?

回答by Adamski

Your question should really be how does the compilerhandle marker interfaces, and the answer is: No differently from any other interface. For example, suppose I declare a new marker interface Foo:

您的问题应该是编译器如何处理标记接口,答案是:与任何其他 interface 没有什么不同。例如,假设我声明了一个新的标记接口Foo

public interface Foo {
}

... and then declare a class Barthat implements Foo:

...然后声明一个Bar实现的类Foo

public class Bar implements Foo {
  private final int i;

  public Bar(int i) { this.i = i; }
}

I am now able to refer to an instance of Barthrough a reference of type Foo:

我现在可以Bar通过类型的引用来引用一个实例Foo

Foo foo = new Bar(5);

... and also check (at runtime) whether an object implements Foo:

...并检查(在运行时)一个对象是否实现Foo

if (o instanceof Foo) {
  System.err.println("It's a Foo!");
}

This latter case is typically the driver behind using marker interfaces; the former case offers little benefit as there are no methods that can be called on Foo(without first attempting a downcast).

后一种情况通常是使用标记接口的驱动程序;前一种情况几乎没有什么好处,因为没有可以调用的方法Foo(无需首先尝试向下转换)。

回答by davidxxx

then how it is handled by the JVM for the classes which implements this marker interface?

那么JVM如何为实现这个标记接口的类处理它呢?

Instances of class implementing a Java marker interface benefit from a specific behavior because some JDK classes or the HotSpot JVMprovide a specific behavior for them.

实现 Java 标记接口的类实例受益于特定行为,因为某些 JDK 类或 HotSpot JVM为它们提供了特定行为。

For example take the Serializableinterface.
If you dig into ObjectOutputStreamand ObjectInputStreamyou can see that the serialization/unserialization behavior are implemented in.

Serializable接口为例。
如果你深入研究ObjectOutputStreamObjectInputStream你可以看到序列化/反序列化行为是在其中实现的。

Here is a snippet of ObjectOutputStream.writeObject0()invoking by ObjectOutputStream.writeObject()that illustrates that :

这是ObjectOutputStream.writeObject0()调用的片段ObjectOutputStream.writeObject(),说明了这一点:

public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants {

   ...
   private void writeObject0(Object obj, boolean unshared) throws IOException   {
            ...    
            if (obj instanceof String) {
                writeString((String) obj, unshared);
            } else if (cl.isArray()) {
                writeArray(obj, desc, unshared);
            } else if (obj instanceof Enum) {
                writeEnum((Enum<?>) obj, desc, unshared);
            } else if (obj instanceof Serializable) {
                writeOrdinaryObject(obj, desc, unshared);
            } else {
                if (extendedDebugInfo) {
                    throw new NotSerializableException(
                        cl.getName() + "\n" + debugInfoStack.toString());
                } else {
                    throw new NotSerializableException(cl.getName());
                }
            }
            ...
    }
}

For the Cloneableinterface, look at the Object.clone()method and you will see that it refers a native method that applies the Cloneablespecification.

对于Cloneable接口,查看Object.clone()方法,您将看到它引用了应用Cloneable规范的本机方法。

In the HotSpot source code, the src\share\vm\prims\jvm.cpp, you can find the Object.clone()implementation :

在 HotSpot 源代码中src\share\vm\prims\jvm.cpp,您可以找到Object.clone()实现:

JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
  JVMWrapper("JVM_Clone");
  Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
  const KlassHandle klass (THREAD, obj->klass());
  JvmtiVMObjectAllocEventCollector oam;

  // I skip all the processing that you can read in the actual source file
  ...

  return JNIHandles::make_local(env, oop(new_obj));
JVM_END 

For this marker interface the behavior is not directly implemented in a JDK class but by the JVM itself but the general idea is the same.

对于这个标记接口,行为不是直接在 JDK 类中实现的,而是由 JVM 本身实现的,但总体思路是相同的。

Can we create any new marker interfaces ?

我们可以创建任何新的标记界面吗?

If you create your own marker interfaces, you should do as the JVM and the JDK classes do to handle built-in instances of class implementing a Java marker interface : that is adding code to handle specifically the instances of your marker interfaces.
The very good answer of Adamskishows the general idea to do that.

如果您创建自己的标记接口,您应该像 JVM 和 JDK 类一样处理实现 Java 标记接口的类的内置实例:即添加代码来专门处理标记接口的实例。
很好的答案Adamski显示了这样做的总体思路。

回答by NPE

As far the compiler and the JVM are concerned, there is absolutely no difference between a marker interface and any other interface.

就编译器和 JVM 而言,标记接口和任何其他接口之间绝对没有区别。

And yes, you can create marker interfaces as you please.

是的,您可以随意创建标记界面。

回答by Raúl

I feel that there might be some logic behind the scenes. How else we get the CloneNotSupportedException when try calling clone() without implementing Cloneable, unless the compiler has some guidelines to check on few things when it sees the clone()!

我觉得这背后可能有一些逻辑。当尝试调用 clone() 而不实现 Cloneable 时,我们如何获得 CloneNotSupportedException ,除非编译器有一些指导方针来在它看到 clone() 时检查一些事情!

http://javamagic.wordpress.com/2011/12/02/marker-interface-in-java-what-why-uses-etc/

http://javamagic.wordpress.com/2011/12/02/marker-interface-in-java-what-why-uses-etc/

As per this thread( Confusion in marker interface), these are all Marker Interfaces .......... Serializable, Clonable, SingleThreadModel, EventListener, RandomAccess, Remote etc.

根据此线程(标记接口中的混淆),这些都是标记接口.......... Serializable、Clonable、SingleThreadModel、EventListener、RandomAccess、Remote 等。

If there is no logic behind the scene OR no special instructions for JVM/compiler to treat them differently, how come they behave as ONLY what is expected out of them (& JVM/compiler understands the difference between Clonable & Serializable)?

如果幕后没有逻辑或 JVM/编译器没有特殊说明来区别对待它们,那么它们为什么只表现出预期的行为(& JVM/编译器理解 Clonable 和 Serializable 之间的区别)?

回答by Nrj

The marker interface helps identify that whether the object under inspection is actually a type (implemented interface) we are interested in. However it is not different than the other interfaces (except that they don't have any behavior obligation)

标记接口有助于识别被检查的对象是否实际上是我们感兴趣的类型(实现的接口)。但是它与其他接口没有什么不同(除了它们没有任何行为义务)

For example, the ObjectOutputStreamcan find that if a class implements Serializable, then the user has explicitly shown his consent that the object can be serialized.

例如,ObjectOutputStream可以发现如果一个类实现了Serializable,那么用户已经明确表示同意该对象可以被序列化。

回答by ARK

The word "serializable" is confusing in this context, as many novice programmers like myself take it to mean that "serializable" interface does the serialization, i.e. the process of converting the abstract data type to bytes. But as the literature shows, serializable interface is just a "marker" and the real work of converting ADT to bytes (I will call this the process of getting metadata) is done by ObjectOutputStream. Similarly deserialization is done by ObjectInputStream.

在这种情况下,“可序列化”这个词令人困惑,因为许多像我这样的新手程序员认为它意味着“可序列化”接口进行序列化,即将抽象数据类型转换为字节的过程。但正如文献所示,可序列化接口只是一个“标记”,而将 ADT 转换为字节的真正工作(我将称之为获取元数据的过程)是由 ObjectOutputStream 完成的。类似地,反序列化是由 ObjectInputStream 完成的。

回答by Praveesh P

Take Exampe of clone(). Actually clone()is defined inside Objectclass. But it is protected. You can use it only if your class is implementing Cloneableinterface. So what happens is, when you implement Cloneable, you get the right to use clone(). Interface doesn't contain any methods! Got it ?

以 为例clone()。实际上clone()是在Object类内部定义的。但它是protected。仅当您的类正在实现Cloneable接口时才能使用它。因此,当您实施 时Cloneable,您将有权使用clone(). 接口不包含任何方法!知道了 ?