gpt4 book ai didi

Java 泛型不兼容类型

转载 作者:行者123 更新时间:2023-12-02 04:46:58 26 4
gpt4 key购买 nike

我有 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
{...}
...}
<小时/>

当我编译时,我得到:

error: incompatible types: inference variable RESPONSE_TYPE has incompatible upper bounds 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)

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

<小时/>

作为旁注,您应该 avoid raw types当你可以的时候:

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

关于Java 泛型不兼容类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29594339/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com