2013-05-07 6 views
8

Ich schrieb gerade eine einfache JUnit Matcher für assertThat(), die Generics erfordert, natürlich.Warum ist es `<T> Type` als Rückgabetyp in Java Generics und nicht` Type <T> `?

Mit etwas Glück fand ich die richtige Syntax für den Rückgabetyp von static <T>Matcher not(Matcher<T> m)..., obwohl ich verstehe nicht, warum

  • im Rückgabetyp seine <T>Matcher und
  • in der Argumentliste seine Matcher<T>

Warum ist es <T>Matcher im Rückgabetyp? Was ist das Konzept dahinter?

Ich komme aus C++ und kann seine Vorlagen dort ziemlich gut behandeln. Ich weiß, dass Generics anders arbeiten, aber das ist, warum das für mich verwirrend ist.

Hier ist meine eigene Matcher Klasse. Schauen Sie sich die statische Hilfs not:

import org.hamcrest.*; 

/** assertThat(result, not(hasItem("Something"))); */ 
class NotMatcher<T> extends BaseMatcher<T> { 
    /** construction helper factory */ 
    static <T>Matcher not(Matcher<T> m) { //< '<T>Matcher' ??? 
     return new NotMatcher<T>(m); 
    } 
    /** constructor */ 
    NotMatcher(Matcher<T> m) { /* ... */ } 
    /* ... more methods ... */ 
} 
+2

Hinweis: Fügen Sie ein Leerzeichen zwischen '' und 'Matcher' hinzu. –

+0

@StiriosDelimanolis warum? Hilft es mir, das dahinter stehende Konzept in den Griff zu bekommen? – towi

+3

Ja, genau. Das ist kein Rückgabetyp. Es sind zwei getrennte Dinge. http://docs.oracle.com/javase/tutorial/extra/generics/methods.html –

Antwort

9

Sie wollen wirklich

static <T> Matcher<T> 

Sie müssen die ersten ‚T‘ den Typ für die generische Methode zu erklären. Das zweite 'T' ist der Typparameter für die Matcher-Klasse.

+0

Oh! Das ist gut. Warum funktioniert mein Programm? Was für eine Art von Matcher werde ich dann hier zurückgeben? Ist es Java, das dies selbst ableitet? – towi

+1

Sie geben einen 'rohen Typ' zurück, der erlaubt, aber nicht empfohlen wird. Sie verlieren alle Arten von Sicherheit. Es ist, als würde man 'List' anstelle von' List ' verwenden. Alle generischen Methoden in dieser Klasse, die den Typ verwenden, werden nur "Object" anstelle von "T". – wolfcastle

+0

* "Alle generischen Methoden in dieser Klasse, die den Typ verwenden, werden nur Object anstelle von T" * ... verwendet, was bedeutet, dass völlig unterschiedliche Überladungen angewendet werden können. Hier ist es die 'not'-Methode, die jetzt einen falschen Rückgabetyp hat, der an' assertThat() 'übergeben wird - der mehrere Überladungen hat, eine davon auch auf' Object' (nehme ich an). Da aber 'equals()' aufgerufen wird, funktioniert es wieder. Ich Glückspilz. Recht? – towi

11

Towi Ich hoffe, diese Abbildung hilft.

enter image description here

Die obige Abbildung ist eine direkte Reaktion auf den Titel der Frage: Warum es <T>Type als Rückgabetyp in Java Generics und nicht Type<T>?

Es gibt noch einige zusätzliche Punkte, die im Towi-Beispiel zu beachten sind, siehe Kommentarfunktion.

+2

Coole Antwort ^^ es sollte jedoch erwähnt werden, dass (a) der von der Methode deklarierte Typparameter T den Typparameter T der Klasse und (b) den Rückgabetyp verdeckt Matcher ist in diesem Fall ein Rohtyp. –

+0

@ MichaelSchmeißer Danke, ich füge eine Notiz in meine Antwort und benutze deinen Kommentar als Ergänzung. Meine Antwort war eine direkte Antwort auf den Titel: * Warum ist es ' Type' als Rückgabetyp in Java Generics und nicht' Type '? *. – Jops

+1

Hmm, eigentlich, da die Methode statisch ist, muss ich widerrufen (a) - die Ts verstecken sich in diesem Fall nicht. –

Verwandte Themen