2012-02-04 8 views
21

voglio fare una classe generica di questa forma:classe generica che accetta uno dei due tipi

class MyGenericClass<T extends Number> {} 

Il problema è, voglio essere accettabile per T essere o Integer o Long, ma non doppio. Quindi le uniche due dichiarazioni accettabili saranno:

MyGenericClass<Integer> instance; 
MyGenericClass<Long> instance; 

C'è un modo per farlo?

risposta

22

La risposta è no. Almeno non c'è modo di farlo usando tipi generici. Vorrei raccomandare una combinazione di generici e metodi di fabbrica per fare ciò che vuoi.

class MyGenericClass<T extends Number> { 
    public static MyGenericClass<Long> newInstance(Long value) { 
    return new MyGenericClass<Long>(value); 
    } 

    public static MyGenericClass<Integer> newInstance(Integer value) { 
    return new MyGenericClass<Integer>(value); 
    } 

    // hide constructor so you have to use factory methods 
    private MyGenericClass(T value) { 
    // implement the constructor 
    } 
    // ... implement the class 
    public void frob(T number) { 
    // do something with T 
    } 
} 

Questo assicura che solo MyGenericClass<Integer> e MyGenericClass<Long> istanze possono essere create. Sebbene sia ancora possibile dichiarare una variabile di tipo MyGenericClass<Double>, sarà sufficiente null.

+0

Dov'è il vantaggio di usare un generico allora? Dato che un metodo con parametro di Tipo T accetterà un numero qualsiasi? –

+0

Nel tuo codice, sicuramente non lo è. Poiché non è possibile scrivere il metodo accettando il parametro di Tipo T. È necessario scrivere due definizioni separate di ciascun metodo, uno per Integer e l'altro per Long. –

+0

@djaqeel Non è vero. Se si tenta di utilizzare il metodo frob con qualcosa di diverso da Long o un intero, si otterrà un'eccezione del compilatore. – luke

2

No, non c'è nulla in generici Java per consentire questo. Potresti considerare di avere un'interfaccia non generica, implementata da FooIntegerImpl e FooLongImpl. È difficile dire senza sapere di più su cosa stai cercando di ottenere.

+0

Ci ho pensato, e avrebbe risolto il mio problema. Mi stavo chiedendo se i java generics mi permettessero di farlo senza dover dichiarare queste classi. Ma non userò le interfacce, perché le implementazioni di entrambe le classi sono le stesse. Creerò una classe protetta di pacchetti astratti e creerò due classi pubbliche che la estendono. – Rafael

+0

E per quanto sto cercando di ottenere, voglio creare una classe che abbia senso per Integer, Long o qualsiasi altro tipo int-like, ma non ha senso usarla con i tipi a virgola mobile. – Rafael

Problemi correlati