2013-04-25 18 views
7

ho definito seguenti classi:Java generici - inferendo nidificato tipo

class Operation<S> 
class GetReservationOperation extends Operation<Reservation> 

Ora vorrei avere una classe come questa:

OperationExecutor<T extends Operation<S>> extends AsyncTask<T,Void,S>{ 
    @Override 
    protected S doInBackground(T... params) { 
     return null; 
    } 
} 

ma questo non sarà la compilazione:

OperationExecutor<GetReservationOperation> executor = new .... 

Perché Java non lo consente?

Dopo qualche tempo mi si avvicinò con la seguente soluzione:

OperationExecutor<T extends Operation<S>,S> extends AsyncTask<T,Void,S>{ 
    @Override 
    protected S doInBackground(T... params) { 
     return null; 
    } 
} 

Ma questo mi costringe a scrivere il seguente:

OperationExecutor<GetReservationOperation,Reservation> executor = new .... 

che sembra strano. C'è un modo per renderlo più bello?

EDIT questo ha funzionato

OperationExecutor<S> extends AsyncTask<Operation<S>,Void,S>{ 
    @Override 
    protected S doInBackground(Operation<S>... params) { 
     return null; 
    } 
} 

OperationExecutor<Reservation> executor = new .... 
executor.execute(getReservationOperation); 
+0

Questo è il motivo per cui la parola chiave 'var' è così utile in C#. Sfortunatamente a java sembra mancare quello. –

+0

Quindi cosa si nasconde dietro '...'? Lo stesso della tua dichiarazione? –

+1

@HighCore Che non è veramente rilevante quindi ... – Zyerah

risposta

3

Ora vorrei avere una classe come questa

OperationExecutor<T extends Operation<S>> extends AsyncTask<T,Void,S>{ 
    @Override 
    protected S doInBackground(T... params) { 
     return null; 
    } 
} 

La ragione per cui questo non funziona è perché S hasn' t stato dichiarato ovunque, indicato solo come un ty argomento nel limite T. Java ha bisogno di essere dichiarato S per altri riferimenti ad esso, ad esempio protected S doInBackground e AsyncTask<T,Void,S>.

Una cosa che si potrebbe considerare è se OperationExecutor deve essere generico per un tipo specifico di Operation<S>. Ad esempio, è possibile farlo:

OperationExecutor<S> extends AsyncTask<Operation<S>, Void, S> { 
    @Override 
    protected S doInBackground(Operation<S>... params) { 
     return null; 
    } 
} 
+0

@ user1778240 Esatto, sarebbe necessario 'OperationExecutor ' , in cui è possibile passare 'GetReservationOperation's o qualsiasi altra' Operazione '. –

+1

Il downlocoter può spiegare? –