【问题标题】:Entity from Optional Object (Java 8)来自可选对象的实体 (Java 8)
【发布时间】:2021-03-09 19:15:09
【问题描述】:

我在尝试将实体从包含且可选的 ArrayList 中拉出时遇到一些问题。当我做一个断点时,我得到代码下方的返回。我知道我很接近,但缺乏关于如何从返回给我的数据中提取 GrandClientDataCore@9463 的知识。

编辑在 for 循环之前添加上一行。

Error occured: java.util.Optional cannot be cast to net.glmhc.dmhwebservices.entities.GrandClientDataCores. 
List<GrandClientDataCores> grandClientDataCoresList = getGrandClientDataCoreList(submitMode, grandClientDataCoreId);
for (GrandClientDataCores grandClientDataCores : grandClientDataCoresList) {
    CDCPAErrors request = new CDCPAErrors();
    request.setI(this.service.getRequestInfo(grandClientDataCores, submitMode, staff));
    logToFile(outDir, String.format("req_%s.xml", new Object[] {grandClientDataCores}), request);
    
    CDCPAErrorsResponse response = (CDCPAErrorsResponse) 
    getWebServiceTemplate().marshalSendAndReceive(getWebServiceUri(), request, 
    (WebServiceMessageCallback) new SoapActionCallback("http://tempuri.org/CDCPAErrors"));

    logToFile(outDir, String.format("res_%s.xml", new Object[] {grandClientDataCoreId}), response);
    DmhServicesCdcResponse responseObj = getResponse(submitMode, response);
    this.service.saveResponse(grandClientDataCores, submitMode, responseObj, staff);
    responses.add(responseObj);
}

这是 getGrandClientDataCoreList

 protected List<GrandClientDataCores> getGrandClientDataCoreList(SubmitMode submitMode, String grandClientDataCore) throws Exception {
        List<GrandClientDataCores> grandClientDataCoresList;
        try {
            grandClientDataCoresList = (List<GrandClientDataCores>) this.service.getGrandClientDataCoreList(submitMode, grandClientDataCore);
         } catch ( Exception ex) {
             throw new Exception(ex);
         }

         if (grandClientDataCore == null || grandClientDataCore.isEmpty()) {
             throw new NoDataException("No CDC record to validate.");

         }
        return grandClientDataCoresList;
    }

【问题讨论】:

  • 列表
  • 我的猜测是,这是因为它被 Spring Boot JPA 进一步包装,这使得任何 findbyid 都变成了 Optional。我将在我原来的问题中添加更多代码。
  • @Noobiedamus this.service.getGrandClientDataCoreList 的返回类型是什么?
  • 对象 getGrandClientDataCoreList (SubmitMode paraSubmitMode, String paramString) 抛出异常;来自服务接口的@ETO。

标签: java java-8 casting optional


【解决方案1】:

您必须在可选项上调用get() 以检索其值。您不能只是将Optional&lt;T&gt; 转换为其他东西。根据调试图像,grandClientDataCoresList 的声明如下所示:

List<Optional<GrandClientDataCores>> grandClientDataCoresList ...

因此你需要这样的东西:

for (Optional<GrandClientDataCores> gcdcOpt: grandClientDataCoresList) {
    GrandClientDataCores gcdc = gcdcOpt.get();
    ....

grandClientDataCores 中的值属于 Optional&lt;GrandClientDataCores&gt; 类型。

你的实际错误在这里:

   protected List<GrandClientDataCores> getGrandClientDataCoreList(SubmitMode submitMode, String grandClientDataCore) throws Exception {
        List<GrandClientDataCores> grandClientDataCoresList;
        try {
            grandClientDataCoresList = (List<GrandClientDataCores>) this.service.getGrandClientDataCoreList(submitMode, grandClientDataCore);
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       This cast is invalid
                                       
         } catch ( Exception ex) {
             throw new Exception(ex);
         }

         if (grandClientDataCore == null || grandClientDataCore.isEmpty()) {
             throw new NoDataException("No CDC record to validate.");

         }
        return grandClientDataCoresList;
    }

您会发现this.service.getGrandClientDataCoreList 返回的实际类型是List&lt;Optional&lt;GrandClientDataCores&gt;&gt;,因此您必须在许多地方相应地更新您的代码。对于初学者...

   protected List<Optional<GrandClientDataCores>> getGrandClientDataCoreList(SubmitMode submitMode, String grandClientDataCore) throws Exception {
        List<Optional<GrandClientDataCores>> grandClientDataCoresList;
        try {
            grandClientDataCoresList = this.service.getGrandClientDataCoreList(submitMode, grandClientDataCore);
         } catch ( Exception ex) {
             throw new Exception(ex);
         }

         if (grandClientDataCore == null || grandClientDataCore.isEmpty()) {
             throw new NoDataException("No CDC record to validate.");

         }
        return grandClientDataCoresList;
    }

以及您调用此方法的任何地方。

【讨论】:

  • 当我尝试这个for (GrandClientDataCores grandClientDataCores : grandClientDataCoresList.get()) { 它要求我输入一个整数。如果我只为 Ss&Gs 输入一个 int,我会得到 foreach not applicable to type 'net.glmhc.dmhwebservices.entities.GrandClientDataCores'
  • 这不是get() 所在的地方。我会更新我的答案。
  • 吉姆我尝试了你更新的答案,但它给了我这个错误。请注意,我确实更新了上面的原始问题,也许这就是为什么? ` 必需类型:GrandClientDataCores 提供:可选 `
  • “但它给我带来了这个错误” -- 哪个错误?根据您发布的图片,grandClientDataCoresList 绝对是List&lt;Optional&lt;GrandClientDataCores&gt;&gt;。调试图像和您的问题之间存在不一致。
  • 必需类型:GrandClientDataCores 提供:可选 是在我的回答结束时尝试格式化它的错误,我深表歉意。这很可能是 IDE 警告不仅仅是错误。
【解决方案2】:

使用 Optional 的“get()”函数,它将检索对象本身。 请注意,如果此 Optional 中没有填充任何对象,它将引发异常。

【讨论】:

  • 当我尝试这个for (GrandClientDataCores grandClientDataCores : grandClientDataCoresList.get()) { 时,它要求我输入一个整数。如果我只为 Ss&Gs 输入一个 int,我会得到 foreach not applicable to type 'net.glmhc.dmhwebservices.entities.GrandClientDataCores'
【解决方案3】:

List 中的 GrandClientDataCores 值被 Optional 包裹,因此您必须检查值是否存在:

grandClientDataCores.isPresent()

如果是,那么就得到它:

grandClientDataCores.get();

或者,您可以这样做:

grandClientDataCores.orElse(new GrandClientDataCores())

我推荐阅读this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多