2013-07-05 11 views
5

Mam klasę z ograniczonym typem parametru z zagnieżdżonymi typami ograniczonymi ze znakami wieloznacznymi. W klasie potrzebuję użyć typów związanych parametrów zagnieżdżonych w wielu metodach. Czy istnieje sposób na zdefiniowanie typu ograniczonego z symbolami wieloznacznymi zamiast ogólnego parametru typu lub przypisanie go do nazwy zmiennej ogólnej, aby można było z łatwością odwoływać się do wielu miejsc?Jawne symbole wieloznaczne zagnieżdżone wieloetapowo lub jako parametr ogólny parametr

Sposób klasa jest teraz realizowany jest jak

class AbstractManager<F extends Filter<? extends Criteria<? extends Type>>> 
    { 
     protected void setFilter(F filter) 
     { 
     setCriteria(f.getCriteria()); 
     } 

     protected <T extends Criteria<? extends Type>> void setCriteria(List<T> criteria) 
     { 
     } 

     protected <T extends Criteria<? extends Type>> void doSomethingWithCriteria(List<T> criteria) 
     { 
      ... 
     } 
    } 

który nie wiąże faktycznie ograniczają rodzaj listy do rodzaju filtr, ale jest wystarczająco dobre w naszej sytuacji. Idealnie typ listy byłby ograniczony do typu filtru przy użyciu konstrukcji, która mogłaby powiązać wywodzący się typ filtra z nazwą bardzo podobną do ograniczonego parametru typu w metodzie, ale na poziomie klasy.

Zasadniczo chciałbym zrobić coś takiego

class <G extends Criteria<? extends Type> AbstractManager<F extends Filter<G>> 

Z tego, co wiem, a może znaleźć, to nie jest możliwe, ale miałem nadzieję, że może nie było niejasne funkcja lub nowa funkcja w Java 7, które umożliwiłoby to. wiem, że to jest możliwe, aby określić drugi parametr typu jak

class AbstractManager<F extends Filter<G>, G extends Criteria<? extends Type>> 

ale nie chcę zajęcia dziecko musiał określić G gdy kompilator można go określić.

Jedynym możliwym rozwiązaniem/rozwiązanie udało mi się znaleźć jest mieć płytkie podklasę z metod fabrycznych podanych w solution na to pytanie Nested Type Parameters in Java iw Java generics - use same wildcard multiple times

+0

Czy możesz podać próbkę tego, czego pożądasz? –

Odpowiedz

1

Jeśli dobrze rozumiem, co zamierza czy zmieni to semantykę twojej klasy. Teraz w aktualnej klasie, można mieć na przykład:

class T1 extends Type {} 
class T2 extends Type {} 
class C1 extends Criteria<T1> {} 
class C2 extends Criteria<T2> {} 
class C3 extends Criteria<T2> {} 
class F1 extends Filter<C1> {} 
class Manager extends AbstractManager<F1> {} 

a potem, mimo Manager jest oparty na F1, niektóre kod użytkownika będzie całkowicie legalne gdyby tak się stało:

Manager m = new Manager(); 
C2 c2 = new C2(); 
C3 c3 = new C3(); 
m.setCriteria(Arrays.asList(new C2[]{c2}); 
m.doSomethingWithCriteria(Arrays.asList(new C3[]{c3}); 

Nie wiem, czy to był twój zamiar, ale jest legalny (z punktu widzenia kompilatora). Jeśli jednak potrafisz w jakiś sposób nazwać ten typ wieloznaczny, używając tej nazwy w swoich metodach, ograniczysz użytkownika swojej klasy do używania tego samego typu we wszystkich metodach. Innymi słowy, w moim przykładzie metody musiałyby zostać wywołane z listami C1.

Podsumowując, jeśli chcesz uzyskać elastyczność, którą posiada twój przykład, musisz powtórzyć wieloznacznik; ale jeśli chcesz ograniczenie, że sposoby wykorzystania tych samych kryteriów jak filtr zarządcy, to faktycznie dało rozwiązanie:

class AbstractManager<F extends Filter<G>, G extends Criteria<? extends Type>> 

(lub utworzyć dedykowany podtyp aby uniknąć powtarzania, jak wspomniano (cokolwiek ci się nie podoba w tym?))

+0

Masz rację, obecna implementacja dopuszcza różne typy w setCriteria/doSomethingWithCriteria niż to, co jest zdefiniowane w Filtrze, stąd problem i potrzeba jakiegoś innego konstruktu/mechanizmu, takiego jak nazywanie ograniczenia na poziomie klasy, jak 'klasa 'lub który jest rozwiązany nieidealnie rozwiązaniem rozwiązania o drugim parametrze. Powinienem był to wyjaśnić w tym pytaniu. – bdrx

+0

OK, wtedy myślę, że krótka odpowiedź na twoje pytanie jest niestety: "Nie" ... I masz rację, mniej gadatliwy mechanizm byłby miły. Myślę, że najlepiej byłoby móc nazwać symbol wieloznaczny nawet w opisie. Na przykład: 'class AbstractManager >' z możliwością ponownego użycia 'F',' C' i 'T' w dowolnym miejscu w klasie. Zawsze możesz zasugerować to społeczności dla Javy 9 :) – Djizeus