2012-02-13 24 views
12

Ho un enumGenerics utilizzando Enum in Java

public enum Days { 
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
THURSDAY, FRIDAY, SATURDAY 

}

Voglio fare una classe che può assumere valori di giorni tipo. Così ho usato Java Generics

public class State<T extend Days> 

Ma c'è un errore

The type parameter T should not be bounded by the final type Days. 
Final types cannot be further extended 

Come posso risolvere questo?

risposta

6

non utilizzano un generici legati. Non c'è bisogno. Basta usare un tipo senza limiti, in questo modo:

public class State<T> { 
    public State(T startState) { 
     // whatever 
    } 
} 

E per usarlo:

State<Days> dayState = new State<Days>(Days.SUNDAY); 

Questa è una classe tipizzata semplice che non ha bisogno di un balzo.

L'unico legato che potrebbe avere senso è un legato a un enum:

public class State<T extends Enum<T>> { 
    public State(T startState) { 
     // whatever 
    } 
} 

Questa versione richiede che il parametro generico essere un enum. Con questa versione l'esempio di utilizzo di cui sopra sarebbe ancora compilare, ma questo non sarebbe la compilazione (per esempio):

State<String> dayState = new State<String>("hello"); 

perché String non è un enum.

+7

Questo non è ciò che l'OP vuole. OP vuole accettare solo Days, niente di niente o enum. Non solo non ha bisogno di un generico destinato a farlo, non ha bisogno di usare generici affatto. – Malcolm

+0

@Malcolm Beh, può usare i generici per la sua classe 'State' (come per il mio codice). Semplicemente non ha bisogno del generico per essere limitato. Vedo cosa intendi, ma * potrebbe * rendere la sua classe generica - sembra una classe a portata di mano avere quell'accordo con lo stato iniziale/corrente – Bohemian

+1

Non ha lo scopo specificato dall'OP. Ha bisogno di una classe che operi su Days o sui suoi figli: "Voglio fare una classe che possa assumere valori di tipo days". Poiché non ci sono bambini per enum, dovrebbe scrivere Giorni esplicitamente. Il tuo codice non limita i valori ai giorni. – Malcolm

5

Non è possibile estendere le enumerazioni in java (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html verso la fine). Quindi non è possibile.

-Se avete bisogno la classe di lavorare solo con il vostro enum non hai bisogno di farmaci generici

-Se invece avete bisogno di lavorare con gli altri enum (non ha senso?) Non è necessario per specificare l'estensione.

Che cosa fa esattamente la tua classe di stato?

9

enumerazioni sono tipi finali, il che significa, non è possibile estendere da loro

un generico come vuole una classe come parametro che è giorni o una classe estesa, ma la classe estesa non è possibile

così l'unico parametro è possibile giorni e non hai bisogno di un generico, se un solo valore è possibile

+1

-1 Ti manca il punto qui. Qualsiasi tipo è possibile - è una classe statale generica. – Bohemian

+0

@Bohemian No, penso che sei tu a non capire il punto. Vedi il commento alla tua risposta. – Malcolm

2

Questo compila bene per me in Java 6:

public enum Days { 
    SUNDAY, 
    MONDAY, 
    TUESDAY, 
    WEDNESDAY, 
    THURSDAY, 
    FRIDAY, 
    SATURDAY 
} 

public class State<T extends Days> { 
    T state; 

    public State(T startState) { 
    this.state = startState; 
    } 
} 

private void test() { 
    State<Days> state = new State<Days> (Days.MONDAY); 
} 

Tuttavia, se si desidera che l'oggetto State per passare da un enum all'altro si sarebbe meglio usare qualcosa come:

public class State<S extends Enum<S>> { 
    final ArrayList<S> states = new ArrayList<S>(); 
    private S state; 

    public State(S startState) { 
    states.addAll(EnumSet.allOf(startState.getClass())); 
    this.state = startState; 
    } 

    public S next() { 
    return state = states.get((state.ordinal() + 1) % states.size()); 
    } 

    public S prev() { 
    return state = states.get((state.ordinal() - 1 + states.size()) % states.size()); 
    } 

    public S set(S newState) { 
    return state = newState; 
    } 

    public S get() { 
    return state; 
    } 
} 

private void test() { 
    State<Days> state = new State<Days> (Days.MONDAY); 
    // ... 
} 
+0

'this.states = (S []) states.toArray();' genera un 'ClassCastException'! Sto lavorando a una soluzione. – OldCurmudgeon

+0

Risolto il problema 'ClassCastException'! – OldCurmudgeon

+0

Ma S potrebbe ancora essere qualsiasi Enum, non deve essere un enume di giorni ... – FBB

5

La cosa da fare qui è

public enum Days{..} 

public class State { // no generic argument! 
    ... 
} 

Così com'è, non si può avere State<T extends Days> perché l'unico modo per soddisfare T extends Days è quello di avere TessereDays. Questo è ciò che significa per Days essere final.

Così, invece, si dovrebbe fare Statenon generica, e utilizzare Days direttamente ovunque si stava tentando di utilizzare T. Non è possibile dichiarare public class State<Days>, perché quindi proverà a trattare Days come variabile tipo , non come classe Days, e questo è non quello che vuoi.