Java 8最有用的功能之一是default接口上的新方法.基本上有两个原因(可能还有其他原因)为什么会被引入:
Iterator.remove()Iterable.forEach()从API设计者的角度来看,我希望能够在接口方法上使用其他修饰符,例如final.在添加便捷方法时,这将非常有用,可防止在实现类时出现"意外"覆盖:
interface Sender {
// Convenience method to send an empty message
default final void send() {
send(null);
}
// Implementations should only implement this method
void send(String message);
}
Run Code Online (Sandbox Code Playgroud)
如果Sender是一个类,上面已经是常见的做法:
abstract class Sender {
// Convenience method to send an empty message
final void send() {
send(null);
}
// Implementations should only implement this method
abstract void send(String message);
}
Run Code Online (Sandbox Code Playgroud)
现在,default并final有明显矛盾的关键字,但默认关键字本身不会一直严格要求 …
在Java 8中,我可以轻松地写:
interface Interface1 {
default void method1() {
synchronized (this) {
// Something
}
}
static void method2() {
synchronized (Interface1.class) {
// Something
}
}
}
Run Code Online (Sandbox Code Playgroud)
我将获得完全同步语义,我也可以在类中使用.但是,我不能synchronized在方法声明上使用修饰符:
interface Interface2 {
default synchronized void method1() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
static synchronized void method2() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以认为,这两个接口的行为方式相同,只是Interface2建立了一个合同上的method1()和method2(),这是比强一点Interface1呢.当然,我们也可能会争辩说default实现不应该对具体实现状态做出任何假设,或者这样的关键字根本不会减轻它的重量.
JSR-335专家组决定不支持synchronized接口方法的原因是什么?
虽然有些人之前已经问过这个问题,但是在Java 8发布之前.
以前,不允许使用静态成员,因为实现细节未在接口中定义.这也是为什么没有什么应该是私有的,因为接口的实现者需要提供实现细节.
这种用Java 8改变了,不是吗?默认方法定义实现细节,静态方法也是如此.那么,为什么仍然不允许这样做?