3

在最近的一次采访中,我被问到“我们怎么能说在 java8 中的功能接口类似于标记接口”。

我无法回答这个问题。

但我认为标记甚至没有任何方法,而功能接口必须有一种方法可以被覆盖。

有人可以帮助我理解这在某些情况下是否是一个有效的论点,还是问题本身是错误的?

4

3 回答 3

7

通常,标记界面是仅通过其存在具有某种效果的界面。换句话说:某种框架将使用instanceof或者可能是反射来识别某些对象或类实现该标记接口的情况,然后根据该信息执行某些操作。

而且我同意您的理解:调用该接口的特定方法不是“标记接口”概念的一部分,至少在我的书中是这样。

在我的书之外,这似乎是一个众所周知的约定:标记接口不声明方法,请参见这里那里。这两个来源都强调:标记接口没有方法或常量。

因此我同意你的立场:该包中的函数和其他接口不是严格意义上的标记接口。

另一方面,我怀疑您会找到该术语的“官方”定义(例如在 Java 语言规范中)。而在没有官方标准的情况下,人们可以随意编造词语的“意义”。

因此,也许您的面试官认为“成为SAM ”界面在某种程度上也是一个“标记”。我很确定你不能因为他的意见起诉他。

于 2019-06-21T19:11:45.383 回答
0

更多细节:功能界面:

来自 Java 8 文档

public @interface FunctionalInterface 一种信息性注释类型,用于指示接口类型声明旨在成为 Java 语言规范定义的功能接口。从概念上讲,函数式接口只有一个抽象方法。由于默认方法有一个实现,它们不是抽象的。如果一个接口声明了一个覆盖 java.lang.Object 的公共方法之一的抽象方法,这也不会计入接口的抽象方法计数,因为该接口的任何实现都将具有来自 java.lang.Object 或其他地方的实现。请注意,函数式接口的实例可以使用 lambda 表达式、方法引用或构造函数引用来创建。如果使用此注解类型对类型进行注解,编译器需要生成错误消息,除非: 该类型是接口类型,而不是注解类型、枚举或类。带注释的类型满足功能接口的要求。然而,

可能是您的面试官想要有关 SAM 的信息。

所以功能接口根本就是一个标记接口。

于 2019-06-21T19:57:31.637 回答
0

为了编译函数式接口,除了用注释接口之外,@FunctionalInterface您还必须声明一个抽象方法作为接口的一部分。

如果你尝试编译一个使用抽象方法注释@FunctionalInterface但没有抽象方法的接口,你会得到:

FunctionalInterfaceAttempt.java:1:错误:意外的@FunctionalInterface 注释
@FunctionalInterface
^
  JavaJava 不是函数式接口
    在接口 JavaJava 中找不到抽象方法
1 个错误

如果您尝试使用多个抽象方法编译相同的接口,您将得到:

JavaJava.java:1:错误:意外的@FunctionalInterface 注释
@FunctionalInterface
^
  JavaJava 不是函数式接口
    在接口 JavaJava 中找到多个非覆盖抽象方法
1 个错误

我认为这种行为不符合标记接口的定义。

于 2019-06-23T20:34:55.130 回答