Java 8的default method与method resolution

先看看下面这个代码例子,
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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值