类中的嵌套泛型多态返回类型

时间:2017-09-04 10:22:36

标签: java generics architecture generic-programming

我有一个类,它将包含要发送到UI的响应。蓝图如下:

class Response<T extends CustomObject> {  
     private String var1;  
     private String var2;  
     private List<T> custom; (eg. customOne, customTwo)
}  

我可以使用不同的对象,例如扩展CustomObject的自定义对象,并且基于该Response类将具有不同的customObject列表。
应用服务逻辑后,我得到一个原始响应,并根据我尝试以不同方式解析的自定义对象 CusomOne和CustomTwo将具有不同的结构:

class CustomOne extends CustomObject {  
    private String v1;  
}  
class CustomTwo extends CustomObject {  
    private String v2;
}  

我有一个抽象的解析函数,它将根据拾取的对象进行调用。该函数定义为:

public abstract ResponsePayLoad<? extends CustomObject> parseResponse(String response);  

ReponsePayLoad是另一个包含CustomObject等其他字段的类。 ResponsePayLoad类的蓝图如下:

class ResponsePayLoad<T extends CustomObject> {  
    private String varX;  
    private List<T> value;  
}  

两个customObjects的解析函数将类似于:

public ResponsePayLoad<customOne> parseResponse(String response){  
    CustomOne one = ; // parsingLogic  
    return one;  
}  
public ResponsePayLoad<customTwo> parseResponse(String response){  
   CustomTwo two = ; // parsingLogic  
    return two;  
}  

当我将代码编写为:

时,在我的服务逻辑中
ResponsePayLoad<CustomObject> responseObj = parseResponse(response);  

我需要将它强制转换为我不想要的ResponsePayLoad 谁能告诉我怎么能跳过使用“?”在抽象函数中仍然保持相同的逻辑?而且我不想像上面定义的那样进行类型转换。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,则返回的parseResponse类型分别为ResponsePayLoad<CustomOne>ResponsePayLoad<CustomTwo>

然后无法将结果存储在

ResponsePayLoad<CustomObject> responseObj = parseResponse(response);

因为你不能低估结果。以通用方式使用

ResponsePayLoad<? extends CustomObject> responseObj = parseResponse(response);

但是,您再次将CustomOneCustomTwo对象存储为CustomObject,这意味着您正在丢失类型信息。然后演员必然。

答案 1 :(得分:0)

你需要施放

的原因
ResponsePayLoad<CustomObject> responseObj = parseResponse(response);  

因为parseResponse方法返回未知类型的ResponsePayload(ResponsePayLoad<? extends CustomObject>)。

这里所理解的是,未知类型可以是CustomObject的子类型。它可以是CustomObject本身(如您的情况),或其某些子类(CustomOneCustomTwo等),但它不需要字面上扩展CustomObject

因此将完整的响应转换为ResponsePayload进一步使其足够通用,尽管编译器必须在执行此操作时对未经检查的强制转换进行警告。

The doc around generics wildcards以更好的例子解释了这一点。

  

...我怎么能跳过使用“?”在抽象功能中仍然保持   同样的逻辑?

避免显式类型转换的另一种方法是从ResponsePayload方法返回parseResponse,将其声明为:

public abstract ResponsePayLoad parseResponse(String response);