在 Java 8 中,如果我有两个具有不同(但兼容)返回类型的接口,反射会告诉我这两个方法之一是默认方法,即使我实际上没有将该方法声明为默认方法或提供方法体。
例如,采用以下代码片段:
package com.company;
import java.lang.reflect.Method;
interface BarInterface {}
class Bar implements BarInterface {}
interface FooInterface {
public BarInterface getBar();
}
interface FooInterface2 extends FooInterface {
public Bar getBar();
}
class Foo implements FooInterface2 {
public Bar getBar(){
throw new UnsupportedOperationException();
}
}
public class Main {
public static void main(String[] args) {
for(Method m : FooInterface2.class.getMethods()){
System.out.println(m);
}
}
}
Java 1.8 产生以下输出:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public default com.company.BarInterface com.company.FooInterface2.getBar()
这看起来很奇怪,不仅因为这两种方法都存在,还因为其中一种方法突然莫名其妙地变成了默认方法。
在 Java 7 中运行相同的代码会产生一些意想不到的结果,尽管仍然令人困惑,因为这两种方法具有相同的签名:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public abstract com.company.BarInterface com.company.FooInterface.getBar()
Java 肯定不支持多种返回类型,所以这个结果还是很奇怪的。
下一个明显的想法是:“好吧,也许这是一种只适用于接口的特殊行为,因为这些方法没有实现。”
错误的。
class Foo2 implements FooInterface2 {
public Bar getBar(){
throw new UnsupportedOperationException();
}
}
public class Main {
public static void main(String[] args) {
for(Method m : Foo2.class.getMethods()){
System.out.println(m);
}
}
}
产量
public com.company.Bar com.company.Foo2.getBar()
public com.company.BarInterface com.company.Foo2.getBar()
这里发生了什么?为什么 Java 将这些作为单独的方法进行枚举,以及其中一种接口方法如何设法成为没有实现的默认方法?