Java 8中的函数式接口为什么可以被称为标记接口?

3
在最近的一次采访中,我被问到一个问题:“如何说在java8中函数式接口类似于标记接口”。
我无法回答这个问题。
但是我认为标记接口甚至没有任何方法,而函数式接口必须有一个方法可被重写。
有人能帮我理解这是否在某些情境下是一个有效的论点或者问题本身就是错误的吗?

似乎这是一个诡计问题。 - ernest_k
1
函数式接口可以有任意数量的默认方法。因此它根本不是标识接口。 - PM 77-1
1
更具体地说,函数式接口需要是SAM类型(单一抽象方法),通常的约定是标记接口既没有常量也没有方法。 - GhostCat
2
我认为函数式接口与标记接口相反:对于标记接口,您需要声明接口但不需要方法;对于函数式接口,您不需要声明接口但需要一个方法。 - daniu
3个回答

7
通常,一个“标记”接口是一种仅仅通过其存在就产生某种效果的接口。换句话说:某些框架将使用 instanceof 或者反射来识别某个对象或类实现了该标记接口的情况,然后基于这些信息执行某些操作。
我同意您的理解:在我的书中,调用该接口的特定方法不属于“标记接口”概念的一部分。
除了我的书之外,似乎这是一个众所周知的惯例:标记接口不声明方法,请参见此处那里。这两个来源都强调:标记接口没有方法或常量。
因此,我同意您的立场:该包中的 Function 和其他接口并不是严格意义上的标记接口。
另一方面,我怀疑你会找不到该术语的“官方”定义(例如在Java语言规范中)。当没有官方标准时,人们可以自由地编造单词的“含义”。
因此,也许你的面试官认为“成为SAM”接口也是一种“标记”。而且我很确定你不能因他的观点而起诉他。

我想补充一点,在我的看法中,标记接口总是有些问题。如果你需要一个标记,请使用注解。最著名的标记接口误用是 Cloneable - Turing85
1
什么意思没有官方定义?标记接口是声明不含方法的接口,功能接口是只有一个抽象方法的接口。虽然它可能没有在语言规范中定义,但我认为它是OCP的一部分,因此是官方规范(可以说)。 - daniu
4
@Turing85,我认为“标记接口”是在注解出现之前的遗物...但我并不完全同意:注解需要框架使用反射。我们有一些自己的标记接口,能够进行instanceof检查比反射更好的“使用概念”。 - GhostCat
3
当我与我们组织中的5个不同团队交流时,我确信会得到5个不同的“单元测试”术语定义。这让我学到了一个重要的教训:除非术语被规范并确定下来,否则不要期望每个人都同意你的定义... - GhostCat
我并不是在争论定义的好处,我只是说这两个术语都有它们各自的定义。 - daniu
显示剩余4条评论

0
更多细节: 功能接口:
来自Java 8文档
注解@FunctionalInterface是一种信息性注解类型,用于指示接口类型声明旨在成为函数式接口,如Java语言规范所定义。从概念上讲,函数式接口具有恰好一个抽象方法。由于默认方法具有实现,因此它们不是抽象的。如果接口声明覆盖java.lang.Object的公共方法之一的抽象方法,则也不计入接口的抽象方法计数,因为接口的任何实现都将具有来自java.lang.Object或其他地方的实现。请注意,可以使用lambda表达式、方法引用或构造函数引用创建功能接口的实例。如果一个类型带有这个注解类型,编译器需要生成一个错误消息,除非:该类型是接口类型而不是注解类型、枚举或类。注释类型满足功能接口的要求。然而,编译器将把符合函数接口定义的任何接口视为函数接口,无论接口声明中是否存在FunctionalInterface注解。
也许你的面试官想了解SAM的信息。
因此,功能接口只是一个标记接口。

0
为了使一个函数式接口编译通过,除了使用@FunctionalInterface注解该接口外,您还需要在接口中声明一个单一的抽象方法。
如果您尝试编译一个带有@FunctionalInterface注解但没有抽象方法的接口,您将会得到以下错误:
FunctionalInterfaceAttempt.java:1: error: Unexpected @FunctionalInterface annotation
@FunctionalInterface
^
  JavaJava is not a functional interface
    no abstract method found in interface JavaJava
1 error
如果您尝试编译具有多个抽象方法的相同接口,则会得到以下错误:
JavaJava.java:1: error: Unexpected @FunctionalInterface annotation
@FunctionalInterface
^
  JavaJava is not a functional interface
    multiple non-overriding abstract methods found in interface JavaJava
1 error
我认为这种行为不符合标记接口的定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接