sch*_*mod 13 java interface return-type java-8 default-method
在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Java 1.8生成以下输出:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public default com.company.BarInterface com.company.FooInterface2.getBar()
Run Code Online (Sandbox Code Playgroud)
这看起来很奇怪,不仅因为两种方法都存在,而且因为其中一种方法突然而且莫名其妙地变成了默认方法.
尽管两种方法具有相同的签名,但在Java 7中运行相同的代码会产生一些不太意外的情况,尽管仍然令人困惑:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public abstract com.company.BarInterface com.company.FooInterface.getBar()
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
产量
public com.company.Bar com.company.Foo2.getBar()
public com.company.BarInterface com.company.Foo2.getBar()
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么Java将这些方法枚举为单独的方法,以及如何将其中一个接口方法设法成为没有实现的默认方法?
它不是default您提供的方法,而是桥接方法.在您定义的父接口中.
public BarInterface getBar();
Run Code Online (Sandbox Code Playgroud)
你必须有一个可以调用的方法来实现它.
例如
FooInterface fi = new Foo();
BarInterface bi = fi.getBar(); // calls BarInterface getBar()
Run Code Online (Sandbox Code Playgroud)
但是,您还需要能够调用它的共变量返回类型.
FooInterface2 fi = new Foo();
Bar bar = fi.getBar(); // calls Bar getBar()
Run Code Online (Sandbox Code Playgroud)
这些是相同的方法,唯一的区别是一个调用另一个并转换返回值.这个方法似乎有一个default实现,因为它在接口上执行此操作.
注意:如果您有多个级别的接口/类,并且每个接口/类具有不同的返回类型,则会累积方法的数量.
这样做的原因是JVM允许多个方法具有不同的返回类型,因为返回类型是签名的一部分.我是调用者必须声明它期望的返回类型,并且JVM实际上并不理解共变量返回类型.
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |