Java泛型不兼容的类型

时间:2015-04-12 20:35:09

标签: java android generics

我有2个扩展的抽象类,以及另一个使用它们的类:

- - - - - - - - 基

public abstract class HttpRequest<RESPONSE_TYPE extends HttpResponse>
{...}
public abstract class HttpResponse<DATA_TYPE>
{...}

- - - - - - - - 扩展

public class MockyTextRequest extends HttpRequest<MockyTextResponse>
{...}
public class MockyTextResponse extends HttpResponse<TextWithTitle>
{...}

----实用------

public class HttpClient
{...
    public <REQUEST_TYPE extends HttpRequest<RESPONSE_TYPE>, RESPONSE_TYPE extends HttpResponse<RESULT_TYPE>, RESULT_TYPE> RESPONSE_TYPE synchronicRequest(@NonNull final REQUEST_TYPE httpRequest, @Nullable final Object tag) throws IOException, HttpException, ParseException
    {...}
...}

当我编译时,我得到:

  

错误:不兼容的类型:推理变量RESPONSE_TYPE有   不兼容的上界HttpResponse,MockyTextResponse

MockyTextResponse httpResponse = HttpClient.get().synchronicRequest(new MockyTextRequest(), null);

任何想法?


斯坦格事实,这次电话

public <REQUEST_TYPE extends HttpRequest<RESPONSE_TYPE>, RESPONSE_TYPE extends HttpResponse<RESULT_TYPE>, RESULT_TYPE> void request(@NonNull final REQUEST_TYPE httpRequest, @Nullable final Object tag, @Nullable final Listener<REQUEST_TYPE, RESPONSE_TYPE> listener)
{...}

称为

HttpClient.get().request(new MockyTextRequest(), MainActivity.this);

工作正常

github

中的完整代码

1 个答案:

答案 0 :(得分:2)

推理算法似乎无法推断出RESPONSE_TYPE的类型。它看起来就像所有三个类型参数MockyTextRequest给出。

确切确定为什么会出现与规范相关的情况,但它与&#34;嵌套&#34;。

有关。

错误可以通过以下方式重现:

// same error on this line
// C (String) is not inferred
m(new ArrayList<List<String>>());

// the compiler is able to infer B from A
// but not C from A
static <A extends List<B>, B extends List<C>, C> void m(A a) {}

这是在Java 8中修复过的东西:

可以提供证人:

MockyTextResponse httpResponse =
    HttpClient.get().
        <MockyTextRequest, MockyTextResponse, TextWithTitle>
        synchronicRequest(new MockyTextRequest(), null);

或者放松类型参数的几种方法:

1

public <
    RESPONSE_TYPE extends HttpResponse<RESULT_TYPE>,
    RESULT_TYPE
> RESPONSE_TYPE synchronicRequest(
    final HttpRequest<RESPONSE_TYPE> httpRequest, final Object tag)

2

public <
    REQUEST_TYPE extends HttpRequest<RESPONSE_TYPE>,
    RESPONSE_TYPE extends HttpResponse<?>
> RESPONSE_TYPE synchronicRequest(
    final REQUEST_TYPE httpRequest, final Object tag)

3

public <
    REQUEST_TYPE extends HttpRequest<RESPONSE_TYPE>,
    RESPONSE_TYPE extends HttpResponse<? extends RESULT_TYPE>,
    RESULT_TYPE
> RESPONSE_TYPE synchronicRequest(
    final REQUEST_TYPE httpRequest, final Object tag)

根据您的描述,似乎#1是最好的。 (#2和#3基本相同,因为无论如何RESULT_TYPE都无法推断。)


另一种方法是定义HttpRequest,如下所示:

class HttpRequest<
    RESPONSE_TYPE extends HttpResponse<RESULT_TYPE>,
    RESULT_TYPE
>

然后:

class MockyTextRequest
extends HttpRequest<MockyTextResponse, TextWithTitle>

public <
    REQUEST_TYPE extends HttpRequest<RESPONSE_TYPE, RESULT_TYPE>,
    RESPONSE_TYPE extends HttpResponse<RESULT_TYPE>,
    RESULT_TYPE
> RESPONSE_TYPE synchronicRequest(
    final REQUEST_TYPE httpRequest, final Object tag)

但这可能会使你的一些代码更冗长。


作为旁注,您应该avoid raw types何时可以:

//                                                  vvv
class HttpRequest<RESPONSE_TYPE extends HttpResponse<?>>