现在,并不是Java接口中的所有方法声明都是公共抽象的,是否应该使用这些修饰符来声明方法?


14

从Java 8开始,default方法被引入接口。有效地,这意味着并非in中的所有方法interface都是abstract

从Java 9(也许)开始,private将允许使用方法。这意味着并非in中的所有方法interface都是public abstract

问题“在Java接口中的方法是否应使用publicaccess修饰符声明?” 在/programming/161633/should-methods-in-a-java-interface-be-declared-with-or-without-a-public-access-m的堆栈溢出中被询问

那里,大多数答案都认为public abstract不应使用,因为中的任何方法都interface不能是public abstract。这已不再是这种情况。

因此,鉴于接口的这些新功能,是否应该public abstract在Java接口方法声明中使用关键字?

在我的特定环境中,我们将有一些经验丰富的软件工程师,但没有Java经验的人会不时读取Java代码。我觉得,public abstract对于那些不熟悉接口如何具有使用这些关键字的不同规则的历史的人来说,现在将关键字排除在外会造成更多的困惑。


5
您是否检查过Java 8 JLS?与SO先前接受的答案相同的部分表明,基于相同的冗余考虑,默认方法的引入并没有改变先前的建议:“缺少default修饰符或static修饰符的接口方法是隐式的abstract...允许,但不鼓励使用样式,请abstract为这种方法声明多余地指定修饰符。” 您为什么期望事情会改变?
蚊蚋

3
我认为事情可能会发生变化,因为隐式方法的条件abstract变得越来越复杂。在Java 9中,同一句话可能是:“缺少default修饰符或static修饰符或private修饰符的接口方法是隐式抽象的...”。另外,未明确使用关键字的辅助参数,即所有接口方法都是public abstract,现在有争议。
戴维·坎贝尔

TBH我不理解“默认”方法背后的原因,甚至静态方法也超出了通常要使用的接口的范围。接口不应被具体化所困扰。这就是为什么它们是有用的参考类型的原因。
Trixie Wolf

1
@TrixieWolf默认方法允许接口演变。以前,与类不同,添加方法会破坏每个实现。现在,只要您拥有良好的候选默认值,就可以扩展接口。考虑添加 streamjava.util.Collection,或Map.getOrDefault()。另一种方法是创建一个新的子接口,并使每个人都无法使用,例如Graphics2D,而没人喜欢!
SusanW

Answers:


2

要扩展StackOverflow答案:

  1. public不需要访问修饰符,因为

    接口主体中的每个方法声明都是隐式公共的(第6.6节)。允许(但不鼓励使用样式)为接口中的方法声明冗余地指定public修饰符。(第9.4节

  2. abstract不需要访问修饰符,因为

    默认方法是在接口中使用默认修饰符声明的方法它的身体总是用一个方块代表

    和...

    缺少默认修饰符或静态修饰符的接口方法是隐式抽象的,因此其主体由分号而不是块表示。

假定默认方法具有主体,而默认方法具有主体,并且接口上的每个方法声明固有地都是公共的,则无需指定任何关键字。


关于答案的评论之一说:

不要让他们思考!我总是在添加公共摘要之前,尽管使用了警察风格,但它使事情变得清晰并提醒读者。现在我被证明是因为Java 8和9使事情变得复杂(user949300)

对StackOverflow问题的评论(已投票18次)反驳了这一点:

这很糟糕,因为将其公开编写意味着它可以是非公开的(Pacerier)

代码的含义,尤其是接口,很重要。


您从StackOverflow引用的评论现在已过时。说添加public修饰符是不好的文字,因为它暗示它可能是非public的,这是矛盾的。该方法可以是非公开的。
大卫·坎贝尔

@DavidCampbell:好吧,我认为在Java 9发布之后,最好问这个问题。:)尚未完成的Java规范可能会回答这个问题。
Greg Burghardt'2

1

缺少block语句含义还不够吗?您是否会extends Object默示声明?

如果开发人员不理解冗余,很可能是他们可能无法完全理解语言功能背后的概念,这比对修饰符感到困惑的问题更大。

开发人员必须了解,接口的目的是创建一个合同,该合同定义客户端如何与对象进行交互。这表明接口中用于对象交互的任何方法都应向客户端公开。

如果将方法声明为私有,则明确表示该方法并不意味着要由客户端调用,就接口而言,这是不容易推断的。


2
不要让他们思考!我总是public abstract在之前添加内容,尽管有警察的风格,但它使事情变得清晰并提醒读者。现在我被证明是正确的,因为Java 8和9使事情复杂化了:-)。Java已经足够冗余了。
user949300 '16

1
@ user949300您还会添加extends Object到每个直接派生自的类Object吗?开发人员应该已经知道的信息,这就是为什么要进行推断的原因。屏幕上的无用信息越少,处理重要信息就越容易。希望我已经说服您走到了黑暗的一面(明白了吗?因为看不到隐含的东西)。如果没有,那值得一试哈哈。最后,归结为使开发人员易于管理代码的原因
Vince Emigh '16

@ user949300这样,您更有可能对接口方法不包含这些声明时的含义感到困惑。也就是说,如果有任何开发人员通过查看您的代码来学习Java,那么您可能会妨碍他们对接口声明语法的理解。
JimmyJames

文斯(Vince),不,我不会扩展Object,尽管当我看到适合的代码时也不会抛出异常。@JimmyJames,如果始终如一地在这样的项目上添加公共摘要,那么我不会感到困惑。我想念什么吗?太太,我的确看到了您的观点。例如,final除非有有趣的要求(例如匿名内部类等),否则我不会在方法参数之前添加
user949300

@ user949300他的意思是,如果用户已经暴露于修饰符的缺乏及其背后的原因,他们可能会问为什么看到修饰符时为什么会有修饰符,使他们认为除了背后的修饰符外,还有背后的实际原因。如果看到的话,我不会坚持extends Object下去,但肯定会升起国旗,让我质疑为什么。正如我在文章中提到的那样,这样做可能意味着开发人员可能对某项工作原理有误解(可能不知道所有对象都已经扩展Object,因此是显式扩展)
Vince Emigh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.