【问题标题】:Nested Generic polymorphic return type in a class类中的嵌套通用多态返回类型
【发布时间】:2017-09-04 18:56:04
【问题描述】:

我有一个包含要发送到 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。
谁能告诉我如何跳过使用“?”在抽象功能中仍然保持相同的逻辑?此外,我不想像上面定义的那样进行类型转换。任何帮助将不胜感激。

【问题讨论】:

    标签: java generics architecture generic-programming


    【解决方案1】:

    如果我理解正确,您的返回类型 parseResponse 分别是 ResponsePayLoad&lt;CustomOne&gt;ResponsePayLoad&lt;CustomTwo&gt;

    那么就无法将结果存入

    ResponsePayLoad&lt;CustomObject&gt; responseObj = parseResponse(response);

    因为你不能降低结果。在一般的方式你会使用

    ResponsePayLoad&lt;? extends CustomObject&gt; responseObj = parseResponse(response);

    但是,您再次将 CustomOneCustomTwo 对象存储为 CustomObject,这意味着您将丢失类型信息。那么演员阵容是必然的。

    【讨论】:

      【解决方案2】:

      你需要施放的原因

      ResponsePayLoad<CustomObject> responseObj = parseResponse(response);  
      

      因为parseResponse 方法返回未知类型的ResponsePayload (ResponsePayLoad&lt;? extends CustomObject&gt;)。

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

      因此,将完整响应转换为 ResponsePayload 进一步使其足够通用,但编译器必须警告您这样做时未经检查的转换。

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


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

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

      public abstract ResponsePayLoad parseResponse(String response);  
      

      【讨论】:

        猜你喜欢
        • 2010-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-20
        相关资源
        最近更新 更多