2009-07-01 10 views
39

Io non sono convinto al 100% che si tratta di una buona idea, ma mi sono imbattuto in un certo codice di oggi che è attualmente implementato come:Come posso richiedere che un parametro generico sia un enum che implementa un'interfaccia?

class MyWidget <T extends Enum<T> > { 
    MyWidget(Map<T, Integer> valueMap) { 
    mValueMap = valueMap; 
    } 

    Map<T, Integer> mValueMap; 
} 

dove MyWidget poi offre metodi che usano mValueMap per convertire il passato-in Enum a/da un Integer.

Quello che mi stava prendendo in considerazione facendo stava cercando di refactoring questo, in modo che avrei dichiaro la mia enumerazione:

interface MyInterface { 
    public Integer getValue(); 
} 

enum MyEnum implements MyInterface { 
    foo, bar; 
    public Integer getValue() { 
    return ordinal(); 
    } 
} 

e sarei quindi in grado di riscrivere MyWidget in qualcosa che sembrava vagamente simile a questo:

public class MyWidget<T extends Enum<T> extends MyInterface> { 
    ... 
} 

e sarebbe quindi in grado di chiamare il metodo getValue() da MyInterface su T tipo oggetti all'interno MyWidget. Il problema, ovviamente, è che "<T extends Enum<T> extends MyInterface>" non è una sintassi valida. C'è un modo per farcela?

Non voglio avere solo MyWidget<T extends MyInterface>, perché è anche importante che T sia un'enumerazione.

Grazie in anticipo!

risposta

77

Utilizzare un '&' invece:

public class MyWidget<T extends Enum<T> & MyInterface> { 
    ... 
} 

I JLS chiamate questo un "tipo di intersezione", ma io riesco a trovare alcuna menzione di esso nel tutorial Java. Devo solo dire che fa esattamente quello che volevi che fosse "extends".

Inoltre, dovrei dire che puoi avere tutti i tipi che desideri nel tipo di intersezione. Quindi, se si voleva, si potrebbe fare:

public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> { 
    ... 
} 

[Nota: Questo esempio di codice non deve essere interpretata come un'approvazione dell'interfaccia Cloneable; era semplicemente a portata di mano al momento]

+0

Il & sintassi è pulito, ma trovo che usarlo di solito si trasforma in un odore di codice, ed è un'indicazione che qualcosa non è proprio giusto con il tuo modello. – skaffman

+2

Sono tendenzialmente d'accordo (penso di averlo usato forse una o due volte, se così fosse). Ma nel caso di enumerazioni che implementano un'interfaccia, penso che sia appropriato. –

+0

Eccellente! Questo è esattamente quello che stavo cercando. Grazie mille! – Sbodd

1

La 203 (nuova nuova IO) roba JSR per JDK 7 sta facendo un sacco di utilizzo di enumerazioni che implementano interfacce (ad esempio: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html). per consentire loro qualche scappatoia in il futuro per le future serie aggiuntive di opzioni enum. Quindi questo è un approccio fattibile e ovviamente quello che è stato scelto dopo un sacco di riflessioni in un grande progetto Sun.

+0

Neat.Spero che java 7 apparirà prima che la mia barba diventi grigia. – skaffman

+0

Scrivendo una piccola quantità di codice che usa questa roba, la mia impressione è che sia un po 'strano. Non posso dire di averlo visto da nessun'altra parte. Nel 2010 uscirà qualcosa con un 7 nel nome, ne sono abbastanza sicuro. Non so se sarà "Java 7" approvato dal JCP. Solo Oracle può rispondere ora ... –

Problemi correlati