2013-05-07 14 views
8

Ho appena scritto un semplice JUnit Matcher per assertThat() che richiede Generics, naturalmente.Perché è `<T> Type` come tipo restituito in Java Generics e non` Tipo <T> `?

Con un po 'di fortuna ho trovato la sintassi giusta per il tipo ritorno di static <T>Matcher not(Matcher<T> m)..., anche se non capisco perché

  • nel tipo ritorno sua <T>Matcher e
  • nel lista degli argomenti sua Matcher<T>

Perché è <T>Matcher nel tipo di reso? Qual è il concetto alla base di questo?

Provengo dal C++ e posso gestire i suoi modelli piuttosto bene. So che il Generics funziona in modo diverso, ma questo è il motivo per cui mi confonde.

Ecco la mia classe Matcher. Guarda l'helper statica 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

Suggerimento: aggiungere uno spazio tra '' e 'Matcher'. –

+0

@SotiriosDelimanolis perché? Mi aiuta ad afferrare il concetto che sta dietro? – towi

+3

Sì, esattamente. Questo non è un tipo di ritorno. Sono due cose separate. http://docs.oracle.com/javase/tutorial/extra/generics/methods.html –

risposta

9

si vuole veramente

static <T> Matcher<T> 

È necessario il primo 'T' per dichiarare il tipo per il metodo generico. La seconda 'T' è il parametro type per la classe Matcher.

+0

Oh! È buono. Perché il mio programma funziona, quindi? Che tipo di matcher ritorno qui, allora? E 'Java a dedurlo da solo? – towi

+1

Si sta restituendo un 'tipo non elaborato', che è consentito, ma scoraggiato. Si perde tutto il tipo di sicurezza. È come usare 'List' invece di' List '. Qualsiasi metodo generico in quella classe che usa il tipo sarà semplicemente 'Object' invece di' T'. – wolfcastle

+0

* "Qualsiasi metodo generico in quella classe che usa il tipo sarà solo Oggetto invece di T" * ... il che significa che possono essere applicati sovraccarichi totalmente diversi. Qui è il 'not'-Method che ora ha un tipo di ritorno errato, che viene passato a' assertThat() '- che ha diversi overload, uno anche su' Object' (presumo). Ma poiché allora viene chiamato 'equals()', funziona di nuovo. Fortunato me. Destra? – towi

11

Towi Spero che questa illustrazione aiuti.

enter image description here

Quanto sopra illustrazione è una risposta diretta al titolo della domanda: Perché è <T>Type come tipo di ritorno in Java Generics e non Type<T>?

Ci sono molti altri punti aggiuntivi da considerare nell'esempio di Towi, vedere la traccia di commenti.

+2

Cool answer ^^ tuttavia, va ricordato che (a) il parametro di tipo T dichiarato dal metodo nasconde il parametro di tipo T della classe 'e (b) il tipo di ritorno Il Matcher in questo caso è di tipo raw. –

+0

@ MichaelSchmeißer Grazie, aggiungo una nota nella mia risposta e uso il tuo commento come supplemento. La mia risposta è stata una risposta diretta al titolo: * Perché è ' Type' come tipo restituito in Java Generics e non' Type '? *. – Jops

+1

Hmm, in realtà, poiché il metodo è statico, devo revocare (a) - gli Ts non si nascondono l'un l'altro in questo caso. –

Problemi correlati