在最近的一次采访中,我被问到“我们怎么能说在 java8 中的功能接口类似于标记接口”。
我无法回答这个问题。
但我认为标记甚至没有任何方法,而功能接口必须有一种方法可以被覆盖。
有人可以帮助我理解这在某些情况下是否是一个有效的论点,还是问题本身是错误的?
在最近的一次采访中,我被问到“我们怎么能说在 java8 中的功能接口类似于标记接口”。
我无法回答这个问题。
但我认为标记甚至没有任何方法,而功能接口必须有一种方法可以被覆盖。
有人可以帮助我理解这在某些情况下是否是一个有效的论点,还是问题本身是错误的?
通常,标记界面是仅通过其存在具有某种效果的界面。换句话说:某种框架将使用instanceof
或者可能是反射来识别某些对象或类实现该标记接口的情况,然后根据该信息执行某些操作。
而且我同意您的理解:调用该接口的特定方法不是“标记接口”概念的一部分,至少在我的书中是这样。
在我的书之外,这似乎是一个众所周知的约定:标记接口不声明方法,请参见这里或那里。这两个来源都强调:标记接口没有方法或常量。
因此我同意你的立场:该包中的函数和其他接口不是严格意义上的标记接口。
另一方面,我怀疑您会找到该术语的“官方”定义(例如在 Java 语言规范中)。而在没有官方标准的情况下,人们可以随意编造词语的“意义”。
因此,也许您的面试官认为“成为SAM ”界面在某种程度上也是一个“标记”。我很确定你不能因为他的意见起诉他。
更多细节:功能界面:
来自 Java 8 文档
public @interface FunctionalInterface 一种信息性注释类型,用于指示接口类型声明旨在成为 Java 语言规范定义的功能接口。从概念上讲,函数式接口只有一个抽象方法。由于默认方法有一个实现,它们不是抽象的。如果一个接口声明了一个覆盖 java.lang.Object 的公共方法之一的抽象方法,这也不会计入接口的抽象方法计数,因为该接口的任何实现都将具有来自 java.lang.Object 或其他地方的实现。请注意,函数式接口的实例可以使用 lambda 表达式、方法引用或构造函数引用来创建。如果使用此注解类型对类型进行注解,编译器需要生成错误消息,除非: 该类型是接口类型,而不是注解类型、枚举或类。带注释的类型满足功能接口的要求。然而,
可能是您的面试官想要有关 SAM 的信息。
所以功能接口根本就是一个标记接口。
为了编译函数式接口,除了用注释接口之外,@FunctionalInterface
您还必须声明一个抽象方法作为接口的一部分。
如果你尝试编译一个使用抽象方法注释@FunctionalInterface
但没有抽象方法的接口,你会得到:
FunctionalInterfaceAttempt.java:1:错误:意外的@FunctionalInterface 注释 @FunctionalInterface ^ JavaJava 不是函数式接口 在接口 JavaJava 中找不到抽象方法 1 个错误
如果您尝试使用多个抽象方法编译相同的接口,您将得到:
JavaJava.java:1:错误:意外的@FunctionalInterface 注释 @FunctionalInterface ^ JavaJava 不是函数式接口 在接口 JavaJava 中找到多个非覆盖抽象方法 1 个错误
我认为这种行为不符合标记接口的定义。