2013-04-25 25 views
7

I zostały zdefiniowane następujące klasy:Java rodzajowych - wnioskowanie typu zagnieżdżonego

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

Teraz chciałbym mieć klasę tak:

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

Ale nie będzie to skompilować:

OperationExecutor<GetReservationOperation> executor = new .... 

Dlaczego na to nie pozwala Java?

Po pewnym czasie wymyśliłem następujące rozwiązanie:

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

Ale to zmusza mnie do napisania co następuje:

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

który wygląda dziwnie. Czy jest jakiś sposób, aby wyglądać ładniej?

EDIT To działało

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

To jest powód, dla którego słowo kluczowe "var" jest tak przydatne w języku C#. Niestety wydaje się, że java tego nie ma. –

+0

Więc co kryje się za '...'? To samo co twoja deklaracja? –

+1

@HighCore Które naprawdę nie jest istotne, więc ... – Zyerah

Odpowiedz

3

Teraz chciałbym mieć klasę jak ten

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

Powodem nie działa dlatego S Hasn” t został zadeklarowany w dowolnym miejscu, tylko z odniesieniem jako ty pe argument w zdaniu T. Java musi być zadeklarowana dla innych odniesień, na przykład protected S doInBackground i AsyncTask<T,Void,S>.

Jedną z rzeczy, które można rozważyć, jest to, czy OperationExecutor musi być ogólne dla określonego typu Operation<S>. Można to zrobić na przykład:

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

@ user1778240 Tak, to musi być 'OperationExecutor ' , do którego można by przekazać operację "GetReservationOperation" lub dowolną inną 'Operację '. –

+1

Czy osoba przekazująca wniosek mogłaby wyjaśnić? –