2015-08-14 17 views
8

In una classe senza tipi generici che voglio dichiarare un campo generico piuttosto complesso simile a questi:Java dichiarazione campo generico

public class Client { 
    private Map<Class<T extends Serializable>, List<Consumer<S extends T>>> classToConsumerTry1; 

    private <T extends Serializable, S extends T> Map<Class<T>, List<Consumer<S>>> classToConsumerTry2; 
} 

promblem è il compilatore Java non mi lascia :)

Così la mia domanda è come introdurre correttamente T e S senza aggiungere tipi al mio client di classe.

Il mio obiettivo è quello di far rispettare la Class essere un sottotipo di Serializable ed il Consumer essere un sottotipo della classe si è scelto per Class.

+0

Perché non si desidera estendere la tua dichiarazione di classe? – Smutje

+0

Perché la mia 'Mappa' dovrebbe poter contenere diversi valori per T e S, non solo quelli definiti nella dichiarazione' Client'. – succcubbus

+0

Dove vengono inizializzati i membri della mappa? In un costruttore? In qualche metodo setter? – Eran

risposta

7

Non è possibile. L'unica opzione è dichiarare i parametri di tipo generico nella dichiarazione della classe Client. Se la tua classe Client non ha parametri di tipo generico, i suoi membri non possono essere generici. È necessario utilizzare i tipi effettivi nella dichiarazione dei membri della classe.

4

Devi introdurre da qualche parte il parametro di tipo, in modo che tu possa utilizzarli nella definizione per i membri della classe.

L'introduzione di un parametro di tipo può essere eseguita solo a livello di classe o a livello di metodo. Nel tuo caso, dovrebbe essere in classe di livello:

public class Client<T extends Serializable, S extends T> { 
    private Map<Class<T>, List<Consumer<S>>> classToConsumerTry1; 

    private Map<Class<T>, List<Consumer<S>>> classToConsumerTry2; 
} 

Questo, tuttavia, implica che per entrambi i membri (classToConsumerTry1 e classToConsumerTry2), T e S sono gli stessi. Se vuoi che siano diversi, devi ottenere questi due valori da due classi diverse, entrambe parametrizzate con parametri di tipo separati.

4

Non si può farlo direttamente sul campo, ma è possibile mantenere la vostra politica tipi con metodi generici (possono esistere anche in classe non generica):

@SuppressWarnings("rawtypes") 
private Map<Class, List> map; 

public <T extends Serializable> void put(Class<T> key, List<Consumer<? extends T>> value) { 
    map.put(key, value); 
} 

@SuppressWarnings("unchecked") 
public <T extends Serializable> List<Consumer<? extends T>> get(Class<T> key) { 
    return map.get(key); 
}