2013-05-15 21 views
18

wiem, że to możliwe, aby dodać wiele ograniczeń do ogólnej definicji klasy, np:Java Generic z 1 parametrem typu i 2 ograniczeń

class Example<I extends Object & Comparable<Object>>{} 

ale chcę ogólnym (MyGeneric), który bierze udział generycznych (SomeGeneric<T>) jako jego parametr typu i aby ograniczyć parametr typu (T) tego rodzaju (np. T extends SomeClass).

Ważne, muszę wiedzieć, rodzaje i SomeClassSomeGeneric zarówno z wnętrza klasy (G i T potrzeby zarówno wiązać). Na przykład, wyobraź sobie coś takiego:

class MyGeneric<G extends SomeGeneric<T>, T extends SomeClass> 
{ 
    public G returnSomeGenericImpl(){} 
    public T returnSomeClassImpl(){} 
} 

pytanie: Powyższe działa, ale wolałbym, jeśli moja klasa miała tylko jeden parametr typu, aby ułatwić życie dla realizatorów mojej klasie. Czy jest sposób na zrobienie tego?

Coś takiego byłoby miło (ale ten konkretny kod jest nieprawidłowy):

class MyGeneric<G extends SomeGeneric<T extends SomeClass>> 
{ 
    public G returnSomeGenericImpl(){} 
    public T returnSomeClassImpl(){} 
} 

Gdybym nie było jasne, ja chętnie próbują wyjaśnić moje intencje.

+6

Nie widzę, jak to mogłoby działać. Jeśli nigdy * nie podasz * konkretnego typu 'T', to jak powinien go odgadnąć kompilator? Jeśli jest tylko jedna opcja, to jest to łatwe, ale zwykle nie ma. A jeśli nie * zależy ci * na konkretnym typie, to dlaczego nie używać ograniczonego typu wieloznacznego (lub lokalnego parametru typu w metodzie). –

+0

@JoachimSauer mówisz, że ze względu na wymazanie tekstu kompilator może wymusić żądane ograniczenie, ale nie może wydobyć/znać typu generycznego? na przykład może zrobić ">' lub nawet > ', ale typ' T' ("?" w tym przypadku) nie jest znany. –

+0

@JoachimSauer odnośnie drugiej części twojego komentarza, oczywiście dbam o konkretny typ, ponieważ chciałbym zwrócić jego instancję z 'public T returnSomeClassImpl() {}' –

Odpowiedz

1

Wygląda to niemożliwe do osiągnięcia.

Po zmniejszając definicji typu o jeden rząd usuwając jeden typ zmiennej i próbuje go zdefiniować,

class G extends SomeGeneric<T extends SomeClass>{} 

nie kompiluje ponieważ parametr typu T nie jest zobowiązany w stosunku do już zdefiniowanego parametru typu. Ale działa to -

class G<T extends SomeClass> extends SomeGeneric<T>{} 

Wynika stąd, że jedynym sposobem parametryzacji dwoma typami jest deklarowanie ich z góry.

+0

@seeta, gdy piszesz "Tak, wywnioskowałem, że jedynym sposobem parametryzacji dwoma typami jest deklarowanie ich z góry." co masz na myśli mówiąc "z góry"? problemem z definiowaniem klasy z góry jest wymuszenie, że wszystkie niezbędne klasy rozszerzają tę klasę ... która nie jest rozwiązaniem. jednak "Wydaje się niemożliwe do osiągnięcia" niestety, myślę, że zgadzam się z –

+0

@nakosspy dotyczące "Klasa ma dwa parametry typu T i G. Oba muszą być zadeklarowane z góry", oczywiście, nikt nigdy nie dyskutował o tym. pytanie dotyczyło tego, w jaki sposób Java pozwala na ich zadeklarowanie. –

+0

@AlexAverbuch Z góry miałem na myśli deklarowanie parametrów nazwą klasy. Jak napisałeś - MyGeneric , T rozszerza SomeClass> –

1

spróbować

class Test1<T extends List<? extends Number>> { 

    public static void main(String[] args) throws Exception { 
     new Test1<ArrayList<Number>>(); 
     new Test1<ArrayList<Integer>>(); 
     new Test1<ArrayList<Object>>(); // compile error 
    } 
} 
+0

Czy mógłbyś dodać trochę więcej wyjaśnień? Więc będzie mi bardziej przydatna do śledzenia tej dyskusji –

+0

mówi "dozwolony typ to lista liczb" –

+0

proszę ponownie przeczytać pytanie: "Ważne, muszę znać typy zarówno z klasy SomeGeneric, jak i SomeClass z klasy (G i T muszą być powiązane) " –

0

Wyobraź sobie:

Type t = someClass(); 
Type g = someGeneric(t); 

foobar(g,t) 

porównaniu do tego

Type g = someGeneric(someClass()); 
foobar(g,?) 

drugi jest rozwiązanie Evgeniy Dorofeev użytkownika. Widzisz problem? Nie można powiązać zmiennej z argumentem. To samo dotyczy generycznych. To, co chcesz zrobić, to:

Type g = someGeneric(Type t = someClass()); 
foobar(g,t) 
+0

dzięki za wyjaśnienie , ale nie sądzę, że to kwalifikuje się jako odpowiedź. może lepiej odpowiedzieć na @EvgeniyDorofeev jako komentarz do jego odpowiedzi ..? –

Powiązane problemy