在解析某些xml文件时,我遇到了一种情况,我必须使用接口作为标签来识别某些标签属于某个类别,例如,我创建了一个 标签 接口来标识这些类用于表示 xml 标签,以及 包含标签 指出某些标签可以是某些标签的子标签之一。

然后我偶然进入这个页面: http://xahlee.org/java-a-day/interface.html (请寻找“界面作为标签“ 会议。)。它说:

问题的要旨是它是语言中的数学无关紧要。作为一种语言的标签机制,为了从软件工程的角度来看,因此不应将其设计为类接口的一部分,因为标签的概念和编程界面的概念在语义上是不同的。

那么界面作为标签一定是一种不好的做法吗?作为一个java程序员,我们还有其他选择吗?

有帮助吗?

解决方案

作为标记的接口在很大程度上已被 Java 5 或更高版本中的注释机制所取代。它们允许您添加任意元数据。如果您的接口是空的并且仅充当类标记,那么您应该改用注释。

其他提示

虽然注释可以为标记接口完成的任务提供替代方案,但它们仅在 Java 中可用,并且不能与 IDE 很好地集成:我还使用标记接口来标记项目中的相关概念,然后我可以使用类型层次结构浏览器来查找所有成员(我猜这最终将很快得到主要 IDE 的注释支持)。

至于你提到的文章,我不认为争论如果一个类在语法/结构上“实现”一个接口,那么该接口可以/应该自动应用于该类(“任何类都可以将其声明 [RandomAccess] 为一个接口...”)。在我看来,这是一种倒退的想法。

我认为,在“instanceof”语句中使用此类标记接口的地方使用了反转逻辑,但只要您陷入没有多重继承、方面和注释的语言中,我就看不到更好的方法来完成这无需脱离基本语言。

另请注意,关于空接口始终适用的这种毫无争议的论点也可以应用于注释。

注释不一定是你想要的。标记接口是一种将类型的属性应用到类型本身的方法。例如,如果您要开始编写如下所示的代码:

@interface ContainableTag{}

@ContainableTag public class Foo {}

// ... elsewhere...

/**
 * Adds obj as a child element.
 * @throws IllegalArgumentException if obj is not tagged with 
 *         the ContainableTag annotation.
 */
public void addElement(Object obj){
    if (!obj.getClass().isAnnotationPresent(ContainableTag.class))
        throw new IllegalArgumentException("obj is not a ContainableTag");
    // add the containable tag as an element
}

然后考虑一下您是否真的认为这看起来更好:

interface ContainableTag {}

public class Foo implements ContainableTag {}

// ... elsewhere...

public void addElement(ContainableTag ct){
    // add the containable tag as an element
}

当然,标记接口不提供有关类型本身提供的行为的任何信息,但它 允许其他类型强制执行此非行为属性。如果我肯定会避免很多恼人的错误 ObjectOutputStream 有一个 writeObject(Serializable) 方法而不是 writeObject(Object).

编辑: 我有 并非微不足道的支持 这里。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top