2017-10-23 3 views
0

Ich habe eine einfache generische SchnittstelleGenerisches Interface verhält sich nicht wie erwartet

public interface Person<T> { 
    T foo(T other); 
} 

und eine Klasse

public class Data<T extends Person> { 

     public void doSomething(List<T> data){ 
     data.stream().reduce((a, b) -> (T)a.foo(b)); 
     } 
    } 

, wenn ich mit der Funktion foo Verwendung reduzieren, die den generischen Typ zurückzukehren T annehmen ist Der Compiler sagt, dass es nicht zurückgegeben werden kann, da es sich um einen falschen Rückgabetyp handelt.

Aber wie können Sie sehen, die Methode foo bekommt und zurück T?

auch wenn ich Autovervollständigen mit meinem Arbeitsplatz myObj.foo(obj)
Ich sehe, dass der Rückgabetyp und der Parameter-Typ ist ein Objekttyp. kann mir jemand erklären, warum es passiert, warum es nicht von einem T Typ?

Antwort

1

Sie haben die allgemeinen Parameter von Person angeben:

public class Data<T extends Person<T>> { 
    ... 
} 

Oder Ihre Generika ein um ein bisschen bewegen, ich noch nicht sehen, was das Gefühl, dass generische Parameter machen.

1

Ihr Problem ist, dass Sie den Brief T verwenden zu stehen für zwei völlig verschiedene Parameter des Typs - Klasse vom Typ Parameter in der Person generische Klasse und dem Typ-Parameter in der Data generisch.

Dies sind nicht die gleichen Parameter - und Sie haben es geschafft, sich zu verwirren, indem Sie für beide den gleichen Buchstaben verwenden. Der Compiler ist jedoch nicht verwirrt; und es sagt Ihnen ganz richtig, dass Sie nicht eine T anstelle der anderen verwenden können.

Insbesondere haben Sie versucht, einen Ausdruck zu konvertieren, dessen Typ Tfoo zurückgibt, an den anderen Typ von T.

1

Sie verwechseln hier 2 Parameter. T in

public interface Person<T> { 
    T foo(T other); 
} 

definiert eine Schnittstelle auf paramer Person.

public class Data<T extends Person> { 
    public void doSomething(List<T> data) { 
     data.stream().reduce((a, b) -> (T)a.foo(b)); 
    } 
} 

Definiert einen Parameter der Klasse Data vom Typ Person welche Person<Object> implizit gleich ist.

So ist List<T> Liste von Objekt Person und Verfahren erstreckt foo() Person Rückgabetyp Object ersten Parameters hat, während der Typ reduce Rückkehr erwartet Person Typ sein.

Und dieser Code unterscheidet sich nicht von Ihnen:

public class Data<E extends Person> { 
    public void doSomething(List<E> data) { 
     data.stream().reduce((a, b) -> (E)a.foo(b)); 
    } 
} 
Verwandte Themen