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