Frage Generics-Funktionsaufruf kompiliert nicht in Java 8, das mehrere Schnittstellen erweitert


Ausführen von Java 1.8 JavaSE-1.8 (jdk1.8.0_20)

Diese Klasse:

public class SimpleQuestion {

    public static void main(String[] args) {
        DoNothing();
        DoNothing2();
        DoNothing3();
        DoNothing4();
    }    

    public interface Interface1 {
        public void go();
    }

    public interface Interface2<X> {
        public X go2();
    }

    private static <X, T extends Interface2<X> & Interface1> void DoNothing() {
        return;
    }

    private static <X, T extends Interface2 & Interface1> void DoNothing2() {
        return;
    }

    private static <X, T extends Interface2<X>> void DoNothing3() {
        return;
    }

    private static <T extends Interface2<T> & Interface1> void DoNothing4() {
        return;
    }    

}

gibt den Kompilierfehler aus:

Die Methode DoNothing () im Typ SimpleQuestion gilt nicht für die Argumente ()

Warum das und nicht DoNothing2,3 und 4?


8
2017-10-03 21:01


Ursprung


Antworten:


Die Fehlermeldung scheint sich auf einen Fehler des in definierten Algorithmus zu beziehen Abschnitt 18.5.1 der Spezifikation.

Für DoNothing geht der Algorithmus wie folgt vor (unter Verwendung der Terminologie aus dem obigen Link):

  • Die Typparameter sind

    P1 = X

    P2 = T extends Interface2<X> & Interface1

    und ich werde a1 und a2 für die entsprechenden Inferenzvariablen verwenden.

  • Der anfängliche gebundene Satz ist

    B0 = {a1 <: Object, a2 <: Interface2<a1>, a2 <: Interface1}

  • Es gibt keine Argumente, daher werden an dieser Stelle keine zusätzlichen Grenzen hinzugefügt (B2 = B0).

  • Da es eine Abhängigkeit von a2 auf a1 gibt, versuchen wir zuerst a1 aufzulösen. Es hat eine richtige obere Grenze von Object, also instanziieren wir es dazu. Einbeziehen a1 = Object beinhaltet das Hinzufügen der gebundenen

    a2 <: Interface2<Object>

  • Als nächstes lösen wir a2 auf. Dies hat nun zwei richtige obere Grenzen, also instanziieren wir a2 in ihr glb:

    a2 = Interface2<Object> & Interface1

  • Jede Variable verfügt jetzt über eine Instanziierung, sodass die Auflösung erfolgreich war.

Daher sollte im Gegensatz zur Fehlermeldung der Aufruf von DoNothing anwendbar sein. Dies scheint ein Fehler in Ihrem Java-Compiler zu sein.


4
2017-10-06 15:25