在实现具有有界返回类型的接口时避免编译器警告

时间:2010-07-14 09:51:35

标签: java generics

如何在不收到编译器未经检查的转换的警告的情况下实现ContactService接口:

interface ContactsService
{
    <T extends Response> T execute(Action<T> action);
}

interface Action<T extends Response> { }

interface Response{ }

class GetDetailsResponse implements Response {}

如果我返回GetDetailsResponse的实例,那么我会收到警告: 未选中覆盖:返回类型需要取消选中转化

这是来自谷歌io的gwt最佳实践演示的一个例子。

2 个答案:

答案 0 :(得分:2)

我猜你试过像:

class MyService implements ContactsService {
    @Override
    public <T extends Response> T execute(Action<T> action) {
        return (T)new GetDetailsResponse();
    }
}

这个问题是我可能有另一个实现Response的MyResponse类。然后我可以打电话:

Action<MyResponse> action = new Action<MyResponse>();
// you can't actually instantiate an interface, just an example
// the action should be some instance of a class implementing Action<MyResponse>
MyReponse r = myService.execute(action);

但execute方法返回GetDetailsResponse的实例,该实例与MyReponse不兼容。您需要返回类型T,它由您传递给执行的操作给出。

据我所知,你无法在执行中实例化一个类型为T的新变量(不管没有一些未经检查的强制转换)。您可能需要动作类来为您提供可以从execute返回的Response实例。像这样:

interface Response {
    void setWhatever(String value);
}

interface Action<T extends Response> {
    T getResponse();
}

class MyAction implements Action<GetDetailsResponse> {
    @Override
    public GetDetailsResponse getResponse() {
        return new GetDetailsResponse();
    }
}

class MyService implements ContactsService {
    @Override
    public <T extends Response> T execute(Action<T> action) {
        T response = action.getResponse();
        // do something to Response here like
        response.setWhatever("some value");
        return response;
    }
}

答案 1 :(得分:1)

要实施ContactsService,您必须能够处理任何Response。用户可能会向您传递Action<FooResponse>并希望返回FooResponse,或者可能会提供Action<BarResponse>并希望获得BarResponse。如果您无法做到这一点,那么您就不能满足接口要求。

如果界面想要接受仅支持一种Response的实现,那么它本身就会在<T extends Response>上生成,而不仅仅是其方法。