簡體   English   中英

當兩個接口具有沖突的返回類型時,為什么一個方法成為默認值?

[英]When two interfaces have conflicting return types, why does one method become default?

在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將這些方法枚舉為單獨的方法,以及如何將其中一個接口方法設法成為沒有實現的默認方法?

它不是您提供的default方法,而是橋接方法。 在您定義的父接口中。

public BarInterface getBar();

你必須有一個可以調用的方法來實現它。

例如

FooInterface fi = new Foo();
BarInterface bi = fi.getBar(); // calls BarInterface getBar()

但是,您還需要能夠調用它的共變量返回類型。

FooInterface2 fi = new Foo();
Bar bar = fi.getBar(); // calls Bar getBar()

這些是相同的方法,唯一的區別是一個調用另一個並轉換返回值。 它是一種似乎具有default實現的方法,因為它在接口上執行此操作。

注意:如果您有多個級別的接口/類,並且每個接口/類具有不同的返回類型,則會累積方法的數量。

這樣做的原因是JVM允許多個方法具有不同的返回類型, 因為返回類型是簽名的一部分。 我是調用者必須聲明它期望的返回類型,並且JVM實際上並不理解共變量返回類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM