简体   繁体   中英

Pass generic of wildcard generic data type in java

I have this classes:

public interface DataAccessor<E extends Model, U>

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

this interface:

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

this methods:

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);

...

}

and get compiler error on this 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);

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

I also tried implementing interface with this but same error.

How to fix error ? Is there some acceptable workaround ?

The reason it doesn't work is because the compiler doesn't know whether the two wildcards ( ? extends Model ) actually refer to the same type. You can work around this by creating a helper method to capture the type:

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);
}

Now call the helper:

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

Shmosel has a good solution. I just want to add that, if you have Java 8, you can use a lambda which can infer the right type, contrary to an anonymous class:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM