欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 8的default method与method resolution

程序员文章站 2022-06-04 14:05:22
...
先看看下面这个代码例子,
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
相关标签: Java Java 8