【问题标题】:Can I try multiple things without nesting the try statements?我可以在不嵌套 try 语句的情况下尝试多项操作吗?
【发布时间】:2015-05-01 18:01:57
【问题描述】:

我的程序正在处理一些 JSON 数据。我希望程序随着时间的推移变得非常稳定,并且 JSON 数据可以随着源的更新和改进而改变。这是从数据中返回一些图像文件名的当前函数:

@Override
public String createImgName() {
  try {
    // data["image"]["full"]
    return getJSONData().getJSONObject("image").getString("full");
  }
  catch(JSONException e) {
    try {
      // data["id"] + ".png"
      return  getJSONData().getJSONObject("id")+".png"; 
    }
    catch(JSONException e2) {
      return null;
    }
  }
}

我可以通过try 获取更多图片名称。但是程序会变得非常丑陋。

有没有trying 多个东西直到一个成功的语法?在我的例子中,return 语句会在成功时中断程序,但情况可能并非总是如此。

【问题讨论】:

  • 简而言之,答案是否定的——在一个成功之前,你不能尝试多种方法。
  • 请注意,您使用try-catch 作为“流控制”。这几乎肯定不是您想要的,最佳实践建议避免它。
  • 您也可以在接球后/接球外进行第二次尝试。如果没有发生异常,代码将返回。存在一些差异,但尚不清楚哪个更好。当然,首先避免异常会更好。
  • @NathanielFord 我明白你的意思,但是 JSON 库几乎在每个操作上都会抛出异常,这迫使我编写这样的代码。

标签: java exception-handling try-catch


【解决方案1】:

您可以使用 .has() 或 .isNull() 方法检查可能的键,而不是使用多个 try 语句。

更多信息: http://www.json.org/javadoc/org/json/JSONObject.html#has(java.lang.String) http://www.json.org/javadoc/org/json/JSONObject.html#isNull(java.lang.String)

例如:

@Override
public String createImgName() {
  try {
    JSONObject data = getJSONData();
    // data["image"]["full"]
    if (data.has("image")) {
      return data.getJSONObject("image").getString("full");
    } else if (data.has("id")) {
      return data.getJSONObject("id")+".png";
    }
  }
  catch(JSONException e) {
    return null;
  }
}

【讨论】:

  • 我喜欢这个答案,因为您应该只对真正例外的情况使用异常,而不是作为常规逻辑控制。
  • 只是一个挑剔,但您可以删除 else 以使代码更清晰/干净。
【解决方案2】:

我建议使用 if/else 块来代替 try/catch(最佳实践)。但是对于您确实需要的尝试/捕获,我建议使用面向铁路的编程将它们降至最低。

http://fsharpforfunandprofit.com/posts/recipe-part2/

【讨论】:

    【解决方案3】:

    要回答发布的问题,即您是否可以在多个事物上使用 try 而无需嵌套 try-catch 语句,否。

    但是,您可以做的是,除了其中一个答案中发布的 if-else 之外,您还可以捕获多个东西

    所以也许您可能想要两个控件的组合:

    除了让 getJSONData 抛出异常之外,您还可以让它返回 null,在其中您将对 if-else 语句进行很好的流控制,所有这些都在 try-catch 中,如果发生了非常糟糕/异常的事情,则抛出具体的异常,对应的catch语句会处理。

    try-catch 不是一个好的流控制的原因:异常在抛出时代价高昂,因为即使不使用它也必须保持堆栈跟踪,这在快速和肮脏的情况下很好编程,但不是在性能是关键的情况下。这就是为什么只有在真正异常时才应该抛出异常See this opinion based Q&A on true-false vs exceptions, where my elaboration on that issue is located as well.

    这样的东西会很好:

    public string imgName()
    { 
      try
      {
        JSONdata a = getJSONmethodA();  
        if(a == null) 
            a = getJSONmethodB(); 
        if(a == null) 
            a = getJSONmehtodC();
        return a;
      }
      catch(Exception unresolvableExceptionA)
      { 
           //error handling 
      }
      catch(Exception verybadExceptionB)
      {
           //special error handling for exception B
      }
    

    }

    Here's a related SO question on this multiple catch structure.

    您还可以在try-catch 中添加finally,以获取无论您的尝试是否成功都将始终执行的代码。这在关闭连接时很有用,或者根据您的需要返回 true/false 作为使用该方法的其他函数的状态代码。

    【讨论】:

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