2014-09-16 2 views
6

Wie kann ich eine Methode mit zwei Parametern haben, wobei beide Parameter denselben Betontyp haben?Erzwingen von zwei Parametern einer generischen Methode, um denselben Betontyp zu haben

Zum Beispiel

boolean equals(Object a, Object b) 

ermöglicht a jeglicher Art und b jeglicher Art.

Ich möchte so zwingen, dass a und b den gleichen konkreten Typ haben. Ich habe versucht,

<T> boolean equals(T a, T b) 

und Date und String diesem Verfahren die Eingabe eines Kompilierzeitfehler erwarten, aber ich bekomme keine Fehler, da T zu ? extends Serializable & Comparable lösen wird, da beide Date und String implementiert Serializable und Comparable.

+1

Warum würden Sie das jemals tun wollen? – AJMansfield

Antwort

7

Sie können grundsätzlich nicht. Es gibt keine Möglichkeit, das zu tun. Auch wenn Sie es für einen einfachen Aufruf tun könnten Argumente der verschiedenen Arten zu verbieten, ist es immer umgangen werden könnte, eine Besetzung mit:

equals((Object) date, (Object) string) 

Wenn Sie in der Ausführungszeit Typen der Argumente interessiert sind, Sie können das nur zur Ausführungszeit testen. Es gibt keine Möglichkeit für den Compiler, zu wissen, ob ein Argument des Typs Date einen Wert hat, der ein Verweis auf genaua java.util.Date oder eine Unterklasse ist.

+0

Danke für die blitzschnelle Antwort. – yuku

1

Die Sache ist Ihre Methode Unterschrift

<? extends Object> boolean equals(? extends Object a, ? extends Object b) 

wird, die Ihnen keine Optionen nicht geben. Auch wenn Sie

equals(new Date(), "hello world"); 

der Compiler aufrufen müssen nicht einmal ins Schwitzen brechen und den kleinsten gemeinsamen Vorfahren für Ihre Parametertypen zu bestimmen.

bearbeiten

Interessant. Ich wusste, dass das, was ich oben geschrieben habe, wahr war, aber es sah immer noch ein bisschen komisch aus. Also teste ich

<T> boolean equals(T a, T b) { 
    return true; 
} 

<T,E> boolean equals(T a, E b) { 
    return true; 
} 

Der Compiler schrie an. Der Grund dafür ist, dass der Compiler in der Tat keinen Unterschied macht und schreibt nur beide Methoden als

boolean equals(? extends Object a, ? extends Object b) 

, die nach Typ Löschung

boolean equals(Object a, Object b) 

wird, die genau die gleiche Signatur. In der Tat, wenn ich Ihre Methode equals(T,T) halte und ich eine andere Methode mit der Signatur equals(Object, Object) hinzufüge, fährt der Compiler fort zu sagen, dass ich die gleiche Methode woanders deklariert habe.

Lange Rede, kurzer, Ihre Methode equals(T,T) ist die gleiche wie equals(Object, Object) aufgrund Typ Löschung und daher kann man nicht den gleichen Parametertyp zwingen, zumindest zum Zeitpunkt der Kompilierung, es sei denn Sie speziell equals Methoden für jede implementieren .

Verwandte Themen