Java中标记接口有什么用?

发布于 2024-08-17 01:02:18 字数 63 浏览 5 评论 0原文

当像 Serialized 这样的标记接口中没有任何东西可以实现时,实现它有什么用呢?

When there is nothing to implement in the marker interfaces like Serializable What is the use of implementing it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

ˉ厌 2024-08-24 01:02:18

Joshua Bloch:《Effective Java》第二版,第 179 页

第 37 项:使用标记接口定义类型

...
你可能听到它说标记
注释(第 35 项)制作标记
接口已过时。这个断言是
不正确。标记接口有两个
相对于标记注释的优点。
首先也是最重要的,标记接口
定义一个由以下方式实现的类型
标记类的实例;标记
注释没有。的存在
这种类型允许您捕获错误
在编译时你不能
如果您使用了,则捕获直到运行时
标记注释....

我个人认为我会向约书亚在这个主题上的卓越知识致敬。

Joshua Bloch: Effective Java 2nd Edition, p 179

Item 37: Use marker interfaces to define types

...
You may hear it said that marker
annotations (Item 35) make marker
interfaces obsolete. This assertion is
incorrect. Marker interfaces have two
advantages over marker annotations.
First and foremost, marker interfaces
define a type that is implemented by
instances of the marked class; marker
annotations do not. The existence of
this type allows you to catch errors
at compile time that you couldn’t
catch until runtime if you used a
marker annotation....

Personally I think I'll bow to Joshua's superior knowledge on this subject.

二智少女 2024-08-24 01:02:18

在 Java 的早期版本中,标记接口是声明有关类的元数据的唯一方法。例如,可序列化标记接口允许类的作者声明他们的类在序列化和反序列化时将表现正确。

在现代 Java 中,标记接口没有地位。它们可以完全被注释替代,允许非常灵活的元数据功能。如果您有一个类的信息,并且该信息永远不会改变,那么注释是表示它的一种非常有用的方式。

In earlier versions of Java, Marker Interfaces were the only way to declare metadata about a class. For example, the Serializable Marker Interface lets the author of a class say that their class will behave correctly when serialized and deserialized.

In modern Java, marker interfaces have no place. They can be completely replaced by Annotations, which allow for a very flexible metadata capability. If you have information about a class, and that information never changes, then annotations are a very useful way to represent it.

讽刺将军 2024-08-24 01:02:18

它表明该类(以及因此所有非瞬态字段)是序列化的候选者。如果您正在构建依赖于序列化的框架,您当然可以这样编写一个方法:

public void registerObject(Serializable obj);

限制您准备接受的类。

由于序列化对象需要保持跨系统的兼容性,因此序列化是一个显式设计决策,因此需要使用标记接口来识别此类候选者。

还有一个安全方面。您不想让所有内容都可序列化 - 否则您可能会通过序列化意外暴露(例如)密码或其他敏感数据。

It indicates that the class (and consequently all the fields which aren't transient) are candidates for serialisation. And if you're building a framework reliant on serialisation, you can of course write a method thus:

public void registerObject(Serializable obj);

to limit the classes you're prepared to accept.

Because a serialized object needs to retain compatibility across systems, serialisation is an explicit design decision and hence requires the use of the marker interface, to identify such candidates.

There's also a security aspect. You don't want to make everything serialisable - otherwise you can accidentally expose (say) passwords or other sensitive data via serialisation.

相思碎 2024-08-24 01:02:18

当其他代码根据对象是否实现某些标记接口做出决定时,此类标记接口非常有用。

对于Serialized,将使用反射来序列化对象的字段。

现在注释是首选,因为它们不会传播到子类。

请参阅标记界面模式

Such marker interfaces are useful in the case other code takes decisions depending on whether an object implements some marker interface.

In the case of Serializable, reflection will be used to serialize the fields of the objects.

Now annotations are preferred as they don't propagate to sub-classes.

See Marker interface pattern.

千秋岁 2024-08-24 01:02:18

它们被称为标记接口。顾名思义,它们标记某些对象可用于某些类型的操作。

例如,Serialized 意味着该对象符合 java 序列化条件。

已经讨论过它们是否不应该被注释取代,因为它们的功能非常相似。

They are called marker interfaces. And as the name implies, they mark that some object is available for certain sort of operations.

Serializable means that the object is eligible for java serialization, for example.

It has been discussed whether they shouldn't be replaced by annotations, since their functions are quite similar.

无言温柔 2024-08-24 01:02:18

如果您实现一个接口,那么 instanceof 将为 true。如果您的接口没有任何需要实现的内容,那么您可以使用它来标记带有元数据的类,就像 Java 1.5 及更高版本的注释所做的那样,而不必强制实现者执行任何特殊操作。

If you implement an interface then instanceof will be true. If you interface has nothing to implement then you can use this to mark a class with meta-data like annotations do for Java 1.5 and up without having to force the implementor to do anything special.

○闲身 2024-08-24 01:02:18

您的推理是正确的,空接口不会影响基于字段检查/突变和方法分派的程序的“标准”执行。

但是,标记接口在与反射结合使用时非常有用:库/方法检查(通过反射)对象,并且如果其类实现标记接口,则其工作方式会有所不同。从 Java5 开始,对标记接口的需求非常少 - 可以通过 Java 注释来实现相同的“标记”功能 - (同样)它们的大部分效果将通过基于反射的代码来实现。

You are right in reasoning that an empty interface does not affect the "standard" execution of the program which is based on inspection/mutation of fields and dispatching of methods.

However, marker interface are useful when used in conjunction with reflection: A library/method inspects (via reflection) an object and works differently if its class impplements the marker interface. As of Java5 there's very little need for marker interfaces - the same "marking" facility can be achieved via Java annotations - which (again) most of their effect will be achieved via reflection-based code.

拥抱我好吗 2024-08-24 01:02:18

大多数情况下,我们会在想要检查类的对象是否具有权限的场景中看到标记接口的使用。我们使用 instanceOf 检查权限。

public interface Herbivorous {
}
public interface Carnivorous {
}
public class Cow implements Herbivorous {
    String howMuchGrassConsumed() {
        return "2";
    };
}
public class Lion implements Carnivorous {
    String howManyCowsConsumed() {
        return "2";
    }
}
public class Jungle{
    public static void main(String[] args) {
        Cow cow = new Cow();
        Lion lion = new Lion();
        if(cow instanceof Herbivorous){
            System.out.println("Cow ate so much gress:"+cow.howMuchGrassConsumed());
        }else if(lion instanceof Carnivorous){
            System.out.println("Lion ate so many cows:"+lion.howManyCowsConsumed(););
        }else{
            System.out.println("That's an alien");
        }
    }
}

Mostly we see use of marker interfaces in scenarios where we want to check if an object of a class has a permission. We check for the permission using the instanceOf.

public interface Herbivorous {
}
public interface Carnivorous {
}
public class Cow implements Herbivorous {
    String howMuchGrassConsumed() {
        return "2";
    };
}
public class Lion implements Carnivorous {
    String howManyCowsConsumed() {
        return "2";
    }
}
public class Jungle{
    public static void main(String[] args) {
        Cow cow = new Cow();
        Lion lion = new Lion();
        if(cow instanceof Herbivorous){
            System.out.println("Cow ate so much gress:"+cow.howMuchGrassConsumed());
        }else if(lion instanceof Carnivorous){
            System.out.println("Lion ate so many cows:"+lion.howManyCowsConsumed(););
        }else{
            System.out.println("That's an alien");
        }
    }
}
甜心 2024-08-24 01:02:18

主要目的是告诉编译器对实现了标记接口的类的对象进行区别对待。

The main purpose is to tell the compiler that treat differently for the object of the class which implemented marker interface.

岁月静好 2024-08-24 01:02:18

仔细观察 Java 中的标记接口,例如 Serialized、Clonnable 和 Remote,看起来它们是用来向编译器或 JVM 指示某些内容的。因此,如果 JVM 看到一个类是可序列化的,它会对其执行一些特殊操作,类似地,如果 JVM 看到一个类是实现 Clonnable 的,它会执行一些操作来支持克隆。 RMI 和远程接口也是如此。简而言之,Marker 接口向编译器或 JVM 指示、发出信号或命令。

了解更多: http:// javarevisited.blogspot.com/2012/01/what-is-marker-interfaces-in-java-and.html#ixzz2v6fIh1rw

Looking carefully on marker interface in Java e.g. Serializable, Clonnable and Remote it looks they are used to indicate something to compiler or JVM. So if JVM sees a Class is Serializable it done some special operation on it, similar way if JVM sees one Class is implement Clonnable it performs some operation to support cloning. Same is true for RMI and Remote interface. So in short Marker interface indicate, signal or a command to Compiler or JVM.

Read more: http://javarevisited.blogspot.com/2012/01/what-is-marker-interfaces-in-java-and.html#ixzz2v6fIh1rw

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文