先看看下面这个代码例子,
(1)与(2)分别应该调用哪个版本的方法呢?
Java 8的接口上的default method,或者叫virtual extension method,目的是为了让接口可以“事后”添加新方法而无需强迫所有实现该接口的类都提供新方法的实现。也就是说它的主要使用场景可能会涉及“代码演进”。
所以让我们把例子退回到代码演进的更早阶段。或许以前这段代码是这样的:
此时的(1)处会调用到Foo.bar(long)方法。
但是当IFoo新添加了新方法bar(int)并提供默认实现之后,(1)就会被“劫持”到IFoo.bar(int)的默认实现上,因为这个版本的signature提供了更准确的匹配。
这种“劫持”行为似乎很符合Java的一贯语义,但是很容易给码农挖坑啊orz…
当前版本的Java 8语言规范草案:[url]http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jls-fr-diffs.pdf[/url]
interface IFoo {
default void bar(int i) {
System.out.println("IFoo.bar(int)");
}
}
public class Foo implements IFoo {
public static void main(String[] args) {
Foo foo = new Foo();
foo.bar(42); // (1) invokevirtual Foo.bar(int)void
IFoo ifoo = foo;
ifoo.bar(42); // (2) invokeinterface IFoo.bar(int)void
}
public void bar(long l) {
System.out.println("Foo.bar(long)");
}
}
(1)与(2)分别应该调用哪个版本的方法呢?
Java 8的接口上的default method,或者叫virtual extension method,目的是为了让接口可以“事后”添加新方法而无需强迫所有实现该接口的类都提供新方法的实现。也就是说它的主要使用场景可能会涉及“代码演进”。
所以让我们把例子退回到代码演进的更早阶段。或许以前这段代码是这样的:
interface IFoo {
}
public class Foo implements IFoo {
public static void main(String[] args) {
Foo foo = new Foo();
foo.bar(42); // (1) invokevirtual Foo.bar(long)void
}
public void bar(long l) {
System.out.println("Foo.foo(long)");
}
}
此时的(1)处会调用到Foo.bar(long)方法。
但是当IFoo新添加了新方法bar(int)并提供默认实现之后,(1)就会被“劫持”到IFoo.bar(int)的默认实现上,因为这个版本的signature提供了更准确的匹配。
这种“劫持”行为似乎很符合Java的一贯语义,但是很容易给码农挖坑啊orz…
当前版本的Java 8语言规范草案:[url]http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jls-fr-diffs.pdf[/url]