在Catch IOException块中捕获相同的IOException

时间:2014-08-15 13:38:38

标签: java android exception try-catch ioexception

我的Android代码表现得很有趣。输入流应该并且确实抛出IOException,这正确地导致控制转到// read an error stream。正确读取错误流,调试器将步骤return error_messageerror_message变量包含从错误流中读取的预期字符。然后它会正确地转到// no op块中的finally,我只是为了踢而添加。

然后,它走到return "all hope lost"; !!然后,不再返回调用者,而是进入某些Android系统代码,该代码会抛出SecurityException,其中包含缺少内容权限的消息。

删除finally块没有影响 - 错误仍然存​​在。正在读取的流来自HTTP URL连接。如果服务器返回200没有问题但是如果服务器返回400它会经历上面描述的奇怪路径并尝试抛出奇怪的SecurityException。

try {
  // read an input stream into message
  return message;
} catch (IOException outer) {
  try {
    // read an error stream into error_message
    return error_message;
  } catch (IOException inner) {
    return "all hope lost";
  }
} finally {
  // no op, just to step debugger
}

更新:发布确切的代码和调试跟踪。

try {
  /*x*/ BufferedReader buffered_reader = 
        new BufferedReader(
        new InputStreamReader(
        new BufferedInputStream(http_url_connection.getInputStream())));
  StringBuilder string_builder = new StringBuilder();
  String line;
  for (line = buffered_reader.readLine(); 
       line != null; 
       line = buffered_reader.readLine()) {
    string_builder.append(line);
  }
  return string_builder.toString();
} catch (IOException io_exception) {
  this.io_exception = io_exception;
  BufferedReader buffered_reader = 
       new BufferedReader(
       new InputStreamReader(
       new BufferedInputStream(http_url_connection.getErrorStream())));
  StringBuilder string_builder = new StringBuilder();
  try {
    for (String line = buffered_reader.readLine(); 
         line != null; 
         line = buffered_reader.readLine()) {
      string_builder.append(line);
    }
    /*y*/ String error_message = "server error: " + string_builder.toString();
    return error_message;
  } catch (IOException exception) {
    String level_2_error_message = "level 2 error: " + exception.getMessage();
    return level_2_error_message;
  } finally {
    return "foo";
  }
}

/*x*/会导致按预期跳转到第一个catch。然后按预期执行最多/*y*/的所有行。然后,奇怪的事情就是行/*y*/没有完成,如果没有catch或者{{{},则会立即控制下一个finally块1}}。如果有finally则不会获得最后一个finally阻止。

catch行上字符串缓冲区的内容看起来很完美 - 来自服务器的20个字符的字符串。

1 个答案:

答案 0 :(得分:1)

你说线/* y */

引发了异常

通过阅读该行代码,以下是合理的解释:

  • 例外是NullPointerException,因为string_buildernull。但它不可能。

  • 例外是OutOfMemoryError,因为您没有足够的可用空间来toString()调用来创建新的String对象。

  • StringBuilder可能不是java.lang.StringBuilder,而是您自己写的一些课程。在这种情况下,任何例外都是可能的。

但是,我看不出你将如何在第二个IOException处理程序中结束。


除此之外,唯一的其他可能的解释是该源代码与您实际执行的代码不匹配;例如你忘了重新编译某些内容,或者在上次编译后忘了重新部署。


值得一提的是,return中的finally几乎肯定是错误的。

  • 这意味着您将返回"foo"而不是任何一条错误消息。

  • 如果(例如)string_builder.toString()确实抛出了NPE或OOME,那么return挤压它。

finally return可能会有非直观的行为。肯定不是你应该做的“调试”!!!