2013-05-07 13 views
8

Właśnie napisałem prostą JUnit Matcher dla assertThat(), która wymaga oczywiście Generics.Dlaczego to jest `<T> Typ` jako typ zwracany w języku Java Generics, a nie `Type <T>`?

Dzięki odrobinie szczęścia znalazłem właściwą składnię typu powrotnej z static <T>Matcher not(Matcher<T> m)..., chociaż ja nie rozumiem, dlaczego

  • w rodzaju powrotnej jego <T>Matcher i
  • w lista argumentów jego Matcher<T>

Dlaczego w typie zwracanym jest <T>Matcher? Jaka jest koncepcja tego rozwiązania?

Pochodzę z C++ i mogę obsługiwać jego Szablony tam całkiem dobrze. Wiem, że Generics działa inaczej, ale właśnie dlatego jest to mylące dla mnie.

Oto moja własna klasa Matcher. Spójrz na statycznych pomocnika 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

Wskazówka: Dodaj spację między '' a 'Matcher'. –

+0

@SotiriosDelimanolis dlaczego? Czy pomaga mi to uchwycić koncepcję, która za tym stoi? – towi

+3

Tak, dokładnie. To nie jest typ zwrotu. To dwie oddzielne rzeczy. http://docs.oracle.com/javase/tutorial/extra/generics/methods.html –

Odpowiedz

9

Naprawdę chcesz

static <T> Matcher<T> 

Trzeba pierwszy „T” zadeklarować typ dla metody rodzajowe. Drugie "T" jest parametrem typu dla klasy Matchera.

+0

Oh! To jest dobre. Dlaczego więc mój program działa? Jakiego matchera tu wrócę? Czy to samo dotyczy samej Javy? – towi

+1

Powracasz "surowy typ", który jest dozwolony, ale zniechęcony. Tracisz wszystkie rodzaje bezpieczeństwa. To jak użycie 'List' zamiast' List '. Dowolne ogólne metody w tej klasie, które używają tego typu, będą po prostu 'Object' zamiast' T'. – wolfcastle

+0

* "Dowolne ogólne metody w tej klasie, które używają tego typu, będą po prostu Obiektem zamiast T" * ... co oznacza, że ​​można zastosować całkowicie różne przeciążenia. Tutaj jest to 'not'-Metoda, która ma teraz niepoprawny typ zwracania, który jest przekazywany do' assertThat() '- który ma kilka przeciążeń, jeden z nich także na' Object' (zakładam). Ale ponieważ wywoływane jest 'equals()', to działa ponownie. Mam szczęście. Dobrze? – towi

11

Towi Mam nadzieję, że ta ilustracja pomoże.

enter image description here

Powyższa ilustracja jest bezpośrednią odpowiedzią na pytanie w tytule: Dlaczego <T>Type jako typ zwracany w Java rodzajowych i nie Type<T>?

Jest jeszcze kilka dodatkowych punktów do rozważenia w przykładzie Towi, zobacz komentarz.

+2

Fajna odpowiedź ^^ jednak należy wspomnieć, że (a) parametr typu T zadeklarowany przez metodę ukrywa klasę 'typ parametru T i (b) typ powrotu Matcher w tym przypadku jest typu surowego. –

+0

@ MichaelSchmeißer Dzięki, dodam notatkę w mojej odpowiedzi i wykorzystam twój komentarz jako dodatek. Moja odpowiedź była bezpośrednia odpowiedź na tytuł: * Dlaczego jest ' Typ' jako typ zwracania w Java Generics, a nie 'Type '? *. – Jops

+1

Hmm, ponieważ metoda jest statyczna, muszę odwołać (a) - Ts nie ukrywa się w tym przypadku. –

Powiązane problemy