Digitare i metodi parametrizzati per evitare il casting

2

In una libreria che sto sviluppando ho un metodo factory che assomiglia un po 'a:

public <T> T instantiate(Type targetType) {
    return ...;
}

Sto usando un metodo di tipo parametrizzato per evitare che gli utenti della mia libreria debbano eseguire il cast ogni volta che lo invocano (sarebbe il caso se avessi scelto di restituire Object ).

C'è qualche ragione per cui non è una buona scelta di design?.

Non mi piace che il programmatore possa invocare il mio metodo come:

String s = instantiate(Integer.class);

Che è chiaramente sbagliato.

Sfortunatamente, il metodo richiede un tipo e non una classe, altrimenti avrei potuto scrivere qualcosa del tipo:

public <T> T instantiate(Class<T> targetClass) {
    return ...;
}
    
posta Sergio 25.04.2013 - 23:26
fonte

2 risposte

5

I generici Java semplicemente non possono fare ciò che si vuole che facciano, perché Type non è esso stesso parametrizzato come Class , e non può essere perché copre anche i tipi primitivi, che non possono essere parametri di tipo. Probabilmente incontrerai anche problemi con la mancanza di covarianza. L'aggiunta di un secondo parametro Class è probabilmente la soluzione più semplice.

Il sistema dei tipi di Java, in particolare i suoi generici, non sono molto potenti, almeno rispetto ai linguaggi come Haskell. Ma è abbastanza buono il 99,9% delle volte, e preferirei vivere con alcuni casi limite in cui la sicurezza dei tipi non può essere garantita in fase di compilazione piuttosto che perdermi in costrutti di tipo esoterico (c'è già più di un'opportunità in Java per questo quando tu usa generici annidati con caratteri jolly).

    
risposta data 27.04.2013 - 00:53
fonte
2

Ho provato a fare la stessa cosa abbastanza recentemente e ho avuto problemi. Dai un'occhiata alla mia domanda qui: link

Invece, vorrei aggiungere un secondo parametro a quel metodo, l'oggetto classe del tipo T. In pratica, la tua alternativa combinata con quello che ti serve:

public <T> T instantiate(Type targetType, Class<T> klass) {
    return ...;
}
    
risposta data 25.04.2013 - 23:44
fonte

Leggi altre domande sui tag