Java 8的default method与method resolution
程序员文章站
2022-06-04 14:05:22
...
先看看下面这个代码例子,
(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语言规范草案:http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jls-fr-diffs.pdf
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语言规范草案:http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jls-fr-diffs.pdf