2009-04-13 22 views
311

voglio avere un oggetto di classe, ma voglio forzare qualsiasi classe che rappresenta per estendere di classe A e B. implementare l'interfacciaJava Generics caratteri jolly con le classi più

posso fare:

Class<? extends ClassA> 

Oppure:

Class<? extends InterfaceB> 

ma non riesco a fare entrambe le cose. C'è un modo per fare questo?

risposta

502

In realtà, è possibile fare quello che vuoi. Se si desidera fornire più interfacce o una classe più interfacce, devi avere il tuo jolly simile a questa:

<T extends ClassA & InterfaceB> 

Vedi l'Generics Tutorial a sun.com, in particolare la sezione Bounded Type Parameters, in fondo alla pagina . È possibile elencare più di un'interfaccia, se lo si desidera, utilizzando & InterfaceName per ciascuna di cui si ha bisogno.

Questo può diventare arbitrariamente complicato. Per dimostrare, vedi la dichiarazione di JavaDoc Collections#max, che (avvolto su due righe) è:

public static <T extends Object & Comparable<? super T>> T 
              max(Collection<? extends T> coll) 

perché così complicato? Come detto nelle FAQ di Java Generics: To preserve binary compatibility.

Sembra che questo non funzioni per la dichiarazione di variabili, ma funziona quando si imposta un limite generico su una classe. Quindi, per fare ciò che vuoi, potresti dover passare attraverso alcuni cerchi. Ma puoi farlo. Si può fare qualcosa di simile, mettendo un limite generico tua classe e poi:

class classB { } 
interface interfaceC { } 

public class MyClass<T extends classB & interfaceC> { 
    Class<T> variable; 
} 

per ottenere variable che ha la limitazione che si desidera. Per ulteriori informazioni ed esempi, consulta la pagina 3 di Generics in Java 5.0. Nota, in <T extends B & C>, il nome della classe deve venire prima e le interfacce seguono. E ovviamente puoi solo elencare una singola classe.

+0

Ma perché devo trasmettere l'oggetto a T quando lo si restituisce? –

+0

@BernhardV: è necessario fornire ulteriori informazioni prima di poter rispondere. In quale situazione hai bisogno di lanciare? – Eddie

+79

Questo è utile. Vale la pena ricordare che la classe _must_ viene prima, non si può dire ''. – EricS

11

Non è possibile farlo con parametri di tipo "anonimo" (ad esempio, caratteri jolly che utilizzano ?), ma è possibile farlo con i parametri di tipo "named". Dichiara semplicemente il parametro type a livello di metodo o di classe.

import java.util.List; 
interface A{} 
interface B{} 
public class Test<E extends B & A, T extends List<E>> { 
    T t; 
} 
+0

Perché non sono ammessi i caratteri jolly? io non vedo perché questo non dovrebbe essere valido: ArrayList ; E poi se hai estratto un elemento dalla lista, potresti assegnarlo a una variabile di tipo ClassA o di tipo InterfaceB – Mark

+0

Sostituire il carattere jolly con una variabile è una tecnica eccezionale! Ma non sempre funziona. Ad esempio, Java non consente le variabili di tipo nomi nei tipi di valori di annotazione, mentre consente i caratteri jolly. – sigpwned

Problemi correlati