2016-12-15 1 views
0

Ich habe diese Klassen:Pass Generikum von Wildcard-generischer Datentyp in Java

public interface DataAccessor<E extends Model, U> 

public class Data<T> implements DataMenuItemObservable<T> { 

diese Schnittstelle:

interface Listener<T> { 
    void onResponse(T value); 
} 

diese Methoden:

public interface DataAccessor<E extends Model, U> extends DataMenuItemObservable<E> { 

... 

    public DataAccessor<? extends Model, ?> getPrimaryDataAccessor() 

    void get(int index, Context context, Listener<Data<E>> listener, ErrorListener errorListener); 

... 

} 

und Compiler-Fehler auf diese erhalten code:

DataAccessor<? extends Model, ?> accessor = db.getPrimaryDataAccessor(); 
accessor.get(0, this, new DataAccessor.Listener<Data<? extends Model>>() { 
      @Override 
      public void onResponse(Data<? extends Model> value) { 
      } 
     }, this); 

Idee sagt incompatible types: <anonimous Listener<Data<? extends Model>>> cannot be converted to Listener<Data<CAP#1>>

Ich habe auch versucht Schnittstelle mit this aber gleichen Fehler zu implementieren.

Wie Fehler zu beheben? Gibt es eine akzeptable Problemumgehung?

+0

Was ist die Signatur von 'DataAccessor.get()'? – shmosel

+0

Was ist "Daten"? – shmosel

+0

@smossel Aktualisiert – nikartix

Antwort

3

Der Grund, warum es nicht funktioniert, ist, weil der Compiler nicht weiß, ob die beiden Platzhalter() sich tatsächlich auf denselben Typ beziehen. Sie können durch die Schaffung eine Hilfsmethode dieses Problem umgehen, die Art zu erfassen:

private <E extends Model> void get(DataAccessor<E, ?> accessor); 
    accessor.get(0, this, new DataAccessor.Listener<Data<E>>() { 
     @Override 
     public void onResponse(Data<E> value) { 
      //... 
     } 
    }, this); 
} 

nun die Helfer nennen:

DataAccessor<? extends Model, ?> accessor = db.getPrimaryDataAccessor(); 
get(accessor); 
+0

Vielen Dank! Es funktioniert – nikartix

2

Shmosel hat eine gute Lösung. Ich möchte nur hinzufügen, dass, wenn Sie Java 8 können Sie einen Lambda verwenden, die den richtigen Typ entnehmen kann, im Gegensatz zu einer anonymen Klasse:

DataAccessor<? extends Model, ?> accessor = db.getPrimaryDataAccessor(); 
accessor.get(0, this, value -> { 
     // code 
    }, this); 
+0

Ich habe das nicht bemerkt. Sehr schön. – shmosel