2013-04-25 14 views
7

Ich habe folgende Klassen definiert:Java Generics - Folgern verschachtelten Typ

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

Jetzt würde ich eine Klasse wie diese haben mag:

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

Aber das wird nicht kompilieren:

OperationExecutor<GetReservationOperation> executor = new .... 

Warum lässt Java dies nicht zu?

Nach einiger Zeit, die ich mit der folgenden Lösung kam:

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

Aber das zwingt mich folgendes zu schreiben:

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

Welche seltsam aussieht. Gibt es eine Möglichkeit, es schöner aussehen zu lassen?

EDIT Das funktionierte

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

Das ist der Grund, warum das Schlüsselwort 'var' in C# so nützlich ist. Leider scheint Java das zu vermissen. –

+0

Also was versteckt sich hinter '...'? Das gleiche wie deine Deklaration? –

+1

@HighCore Welches ist nicht wirklich relevant so .... – Zyerah

Antwort

3

Nun möchte ich eine Klasse wie dieses

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

Der Grund haben mag dies nicht funktioniert, weil S hasn‘ t wurde deklariert überall, nur als eine Ty verwiesen pe Argument in T ist gebunden. Java benötigt S, um für andere Verweise darauf deklariert zu werden, zum Beispiel protected S doInBackground und AsyncTask<T,Void,S>.

Eine Sache, die Sie in Betracht ziehen könnten, ist, ob OperationExecutor für einen bestimmten Typ von Operation<S> generisch sein muss. Sie könnten dies stattdessen zum Beispiel tun:

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

@ user1778240 Richtig, es müsste "OperationExecutor " sein , in die Sie 'GetReservationOperation' oder irgendeine andere 'Operation ' übergeben könnten. –

+1

Könnte der downvoter bitte erklären? –