繁体   English   中英

Java泛型不兼容类型

[英]Java Generics Incompatible Types

我有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中

推断算法似乎无法推断RESPONSE_TYPE的类型。 看起来所有三个类型参数都应该MockyTextRequest给出。

我不完全知道为什么,这是相对于该规范的情况下,但它与“筑巢”的事情。

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

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

但这可能会使您的某些代码更加冗长。


附带说明,在可能的情况下,应避免使用原始类型

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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