Riley van Hengstum
Riley van Hengstum

Reputation: 4552

Java 7 generics type inference fails

I have the following method:

protected <T> Func1<ApiResponse<T>, Observable<T>> checkApiSuccess() {
    return new Func1<ApiResponse<T>, Observable<T>>() {
        @Override
        public Observable<T> call(ApiResponse<T> response) {
            if (response.isSuccess()) {
                return Observable.from(response.getResult());
            }

            return Observable.error(new ApiException(response.getError()));
        }
    };
}

Why does this work:

Func1<ApiResponse<LoginResult>, Observable<LoginResult>>
        checkApiSuccessFunc = checkApiSuccess();

return apiService
        .login(params)
        .flatMap(checkApiSuccessFunc);

but this doesn't:

return apiService
        .login(params)
        .flatMap(checkApiSuccess());

I get the compile-time error no suitable method found for flatMap(Func1<ApiResponse<Object>>, Observable<Object>). Somehow when using the method directly the type T can't be mapped to LoginResult anymore.

Upvotes: 1

Views: 297

Answers (2)

assylias
assylias

Reputation: 328618

The type inference probably can't determine that the T should be a LoginResult. It may work with Java 8 where the type inference system has been improved.

You could try using a target type to help the compiler:

flatMap(this.<LoginResult> checkApiSuccess())

Upvotes: 2

RealSkeptic
RealSkeptic

Reputation: 34628

In

Func1<ApiResponse<LoginResult>, Observable<LoginResult>>
        checkApiSuccessFunc = checkApiSuccess();

return apiService
        .login(params)
        .flatMap(checkApiSuccessFunc);

The compiler infers from the declared type of checkApiSuccessFunc what the return type of checkAPISuccess() is, and from this infers everything inside it.

But in

return apiService
        .login(params)
        .flatMap(checkApiSuccess());

There is really not enough information to infer the type of checkApiSuccess(). flatMap expects the function to take an <? super T> parameter. So it expects something which is a superclass of whatever login emits, and since you have nothing that limits it, it infers Object. You haven't mentioned what the signature function that this return is called for is.

Upvotes: 0

Related Questions