标签: marker-interfaces

Java中的标记接口?

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

但最近我了解到它实际上与编译器或JVM无关.例如,在的情况下,Serializable接口的方法writeObject(Object)ObjectOutputStream不喜欢的东西instanceOf Serializable,以检测类实现是否Serializable与抛出NotSerializableException相应.一切都在代码中处理,这似乎是一个设计模式,所以我认为我们可以定义自己的标记接口.

现在我怀疑了:

  1. 上面提到的标记接口的定义在第一点是错误的吗?那么我们如何定义Marker接口呢?

  2. 而不是使用instanceOf运算符为什么不能使方法类似于writeObject(Serializable)有一个编译时类型检查而不是运行时?

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

java design-patterns marker-interfaces

129
推荐指数
5
解决办法
9万
查看次数

使用标记接口而不是属性的令人信服的理由

它已经讨论过堆栈溢出,我们应该更喜欢属性标记接口(接口没有任何成员).MSDN上的接口设计文章也断言了这个建议:

避免使用标记接口(没有成员的接口).

自定义属性提供了标记类型的方法.有关自定义属性的更多信息,请参阅编写自定义属性.如果可以在执行代码之前推迟检查属性,则首选自定义属性.如果您的方案需要编译时检查,则无法遵守此准则.

甚至还有一个FxCop规则来强制执行此建议:

避免空接口

接口定义提供行为或使用合同的成员.无论类型在继承层次结构中出现何种位置,接口描述的功能都可以采用任何类型.类型通过为接口的成员提供实现来实现接口.空接口不定义任何成员,因此,不定义可以实现的合同.

如果您的设计包含期望实现类型的空接口,则可能使用接口作为标记,或者标识一组类型的方法.如果此标识将在运行时发生,则完成此操作的正确方法是使用自定义属性.使用属性的存在或不存在或属性的属性来标识目标类型.如果标识必须在编译时进行,则可以使用空接口.

本文仅说明了您可能忽略警告的一个原因:何时需要对类型进行编译时识别.(这与界面设计文章一致).

如果在编译时使用接口标识一组类型,则可以安全地从此规则中排除警告.

实际问题是:Microsoft在框架类库的设计中(至少在几种情况下)不符合他们自己的建议:IRequiresSessionState接口IReadOnlySessionState接口.ASP.NET框架使用这些接口来检查它是否应该为特定处理程序启用会话状态.显然,它不用于类型的编译时识别.他们为什么不这样做?我可以想到两个潜在的原因:

  1. 微优化:检查对象是否实现接口(obj is IReadOnlySessionState)比使用反射检查属性(type.IsDefined(typeof(SessionStateAttribute), true))更快.大多数时候差异可以忽略不计,但它实际上可能对ASP.NET运行时中的性能关键代码路径很重要.但是,他们可以使用的解决方法就像为每个处理程序类型缓存结果一样.有趣的是,ASMX Web服务(具有类似性能特征)实际上使用EnableSession属性WebMethod属性来实现此目的.

  2. 与使用第三方.NET语言的属性装饰类型相比,可能更有可能支持实现接口.由于ASP.NET被设计为与语言无关,并且ASP.NET 根据指令的属性为类型(可能在CodeDom的帮助下以第三方语言生成)生成代码,因此可能会生成更多感觉使用接口而不是属性.EnableSessionState<%@ Page %>

使用标记接口而不是属性的有说服力的原因是什么?

这只是一个(过早?)优化还是框架设计中的一个小错误?(他们认为反射是"红眼睛的大怪物"吗?)思想?

.net asp.net attributes interface marker-interfaces

55
推荐指数
4
解决办法
5427
查看次数

Java中标记接口的用途是什么?

什么都没有在Serializable等标记接口中实现..实施它有什么用?

java annotations marker-interfaces

51
推荐指数
5
解决办法
4万
查看次数

Java:什么可以和什么不能序列化?

如果Serializable接口只是一个标记接口,用于传递有关java中类的元数据 - 我有点困惑:

在阅读了java的序列化算法(元数据从下到上,然后是从上到下的实际实例数据)的过程之后,我无法真正理解通过该算法无法处理哪些数据.

简而言之:

  1. 什么数据可能导致NotSerializableException
  2. 我怎么知道我不应该implements Serializable为我的课程添加条款?

java serialization marker-interfaces

24
推荐指数
4
解决办法
3万
查看次数


为什么java注释?

我想问为什么java注释使用了这么多...我知道他们替换了例如jpa中的xml配置,但为什么这种配置会被使用呢?考虑一下这段代码:

@Entity 
class Ent{
   // some fields
}
//... somewhere in the other file far far away
class NonEnt{
   // whatever here
}
Run Code Online (Sandbox Code Playgroud)现在,当我尝试将其置于持久化上下文中时,使用EntityManager's persist方法,我会在尝试持久化NonEnt实例时遇到运行时错误(更好的是获得编译错误).对我来说有明显的解决方案,强制实体实现一些无方法接口,而不是使用@Annotations.但这在框架设计师中并不流行,这个解决方案的缺点是什么?
谢谢回答...

java annotations marker-interfaces

15
推荐指数
2
解决办法
5052
查看次数

为什么选择ObjectOutputStream.writeObject(Object o); 但不是ObjectOutputStream.writeObject(Serializable o)

在Java中,我们使用序列化的writeObject(Object obj)方法.ObjectOutputStreamObject

但是因为该方法只接受实现java.io.Serializable接口的对象(或者它会抛出NotSerializableException),为什么它仍然使用Object参数而不是SerializablewriteObject(Serializable o)

有任何设计考虑因素吗?

java serialization objectoutputstream marker-interfaces

10
推荐指数
0
解决办法
184
查看次数

可串行标记接口是否包含默认方法?

我认为它不能,因为标记接口原则是没有任何方法,但由于默认方法不是抽象的我不确定.

java interface marker-interfaces java-8 default-method

10
推荐指数
4
解决办法
1168
查看次数

标记界面与空抽象类

我在使用标记接口或空抽象类之间做出决定时遇到困难.

我有两个类BrokerResponseNotification,不具有结构相似性.连接它们的唯一方法是需要订阅.

void register(Receivable receivable, BrokerObserver observer)
Run Code Online (Sandbox Code Playgroud)

我不知何故不喜欢使用a Marker Interface,因为它违反了a 的基本定义Interface.另一方面,使用abstract super课程会让我感到不舒服,因为这两个课程彼此没有关系.

在这种情况下,通常更可取的方法是什么?为什么?

编辑1

我忘了提一下,这BrokerResponse是一个抽象类本身,它有几个子类来确定相应的类型.

java abstract-class software-design marker-interfaces

9
推荐指数
1
解决办法
1036
查看次数

空与标记接口

任何人都可以详细说明Java中Null接口和Marker接口之间的核心区别是什么.我在一次采访中被问到这个问题.

谢谢.

java marker-interfaces

8
推荐指数
1
解决办法
3122
查看次数