【问题标题】:Java executes 'catch' block with no error, and somehow still runs 'try' blockJava 执行 'catch' 块没有错误,并且不知何故仍然运行 'try' 块
【发布时间】:2012-05-14 14:28:06
【问题描述】:

我对以下代码有疑问。首先,我是 Java 的新手,有其他几种语言的经验。

当我在 Android 上运行以下命令时,它在 "in.close();" 处出错,跳转到 catch 块并运行 Return "";问题是,该函数没有返回空字符串,它成功返回了正确的 json 数据,即使调试器说它没有运行 return json,而是运行 return "";

public void fetch() {

    // Get the JSON of the image gallery
    String json = getJSON();

    // json somehow has the actual correct json data and not an empty string!

};

private String getJSON() {

    try {
        // Create a URL for the desired page
        URL url = new URL("http://imgur.com/gallery.json");

        // Read all the text returned by the server
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
        String json = in.readLine();
        in.close();
        return json; // <-- debugger doesn't break here!
    }
    catch(Exception e) {
        Log.e("getJSON", e.getMessage());
        return ""; // <-- debugger breaks here! Cat Log shows nothing!
    }
}

我将完全相同的代码复制到 Java 控制台中,这样我就可以输出错误消息并在带有断点的调试器中观察它,并且代码执行时不会出错。

    try {
        // Create a URL for the desired page
        URL url = new URL("http://imgur.com/gallery.json");

        // Read all the text returned by the server
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        String json = in.readLine();
        in.close();
        System.out.println(json);
}
catch(Exception e) {
    System.out.println(e.getMessage());
}   

到底发生了什么?为什么我的代码在 Java 控制台中运行时在 Android 上运行会出错?为什么当它出错时它不返回错误应该返回的内容;和空字符串?如何在 Android 中查看错误消息?

【问题讨论】:

  • 您是否在清单文件中设置了 Internet 权限?
  • 你确定你得到一个错误?您可以在您的异常上调用e.printStackTrace() 以获取确切的异常类型以及它发生在哪一行。这适用于常规 java 和 Android(在 android 上它显示在 LogCat 中)。
  • 我在返回之前在我的 catch 块中添加了 e.printStackTrace(),但我的 LogCat 中没有显示任何内容。如果函数正确返回 json,并且没有输出错误,那么为什么调试器会在我在 catch 块中返回的断点处中断?

标签: java android


【解决方案1】:

你应该确保包括

<uses-permission android:name="android.permission.INTERNET" />

androidManifext.xml 中的权限。

您正在尝试从远程位置检索数据。 在 Java 控制台上,您可以在没有此类权限的情况下执行此操作,但在 Android 中则不行。

【讨论】:

  • 被包含了,并且在Android中成功返回了json数据,但是跳转到catch块运行return "",但是函数实际上还是以某种方式返回了json数据而不是空字符串。
  • 您应该清理您的项目并重试。 Android 调试器有时会做一些奇怪的事情。
【解决方案2】:

忘记 Android 中的“System.out.println”。 您可以在 Eclipse 中使用“Logcat”视图。这用于显示您想要从设备中获取的每个日志。 此外,您可以将“System.out.println(json);”替换为“Log.e("MyApp", "Here is my Json: '"+json+"'");”,您将在 logcat 中看到您的 json...;)

关于您的异常,您在框架中有一个方法可以自动将异常记录在 logcat 中:“myException.printStackTrace();

【讨论】:

  • 还有一个 Log.e() 方法:Log.e(String, String, Throwable)。它也可以用于记录异常。
  • 当我在返回前的 catch 块中使用它时,我的 LogCat 中没有任何内容出现,即使调试器在返回时中断。我的 LogCat(位于其中)中唯一的内容是:?:??: W/?(?): Unable to open log device '/dev/log/main': No such file or directory
  • 你有连接设备吗?甚至模拟器?然后进入“DDMS透视图”,在列表中点击它,然后“Window/Show View/Log Cat”...
  • 我正在使用已连接的手机。 Log Cat 在 Debug 选项卡和 DDMS 选项卡中可见。 Log Cat 中什么也没有出现。我正在使用:catch(Exception e) { Log.e("getJSON", e.getMessage());返回 ””; }
  • 您是否尝试在 catch 子句中放置一个断点并在调试模式下运行您的项目?这是了解正在发生的事情的最佳方式...
【解决方案3】:

Reader 读取文本,即 InputStream 二进制数据。桥 InputStreamReader 需要字符编码,并在您的情况下采用默认的操作系统编码。

所以最好明确地使用编码:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));

因为 JSON 最好是 UTF-8,我已经给出了。但是 Android 上的默认编码是 UTF-8,你可能是 Cp1252。所以可能还有其他问题。

【讨论】:

    【解决方案4】:

    您的代码似乎是正确的。如果您确实看到返回的 JSON,那么您没有从 close 获得任何 IOException

    编辑

    您更新后的源代码清楚地表明,finally 没有返回或重试逻辑在这里起作用。很好。

    在您的环境中访问以下设置:Window / Preferences / Run/Debug / Launching /“当工作区包含断点时以调试模式启动”

    将此设置为始终提示。 (如果之前是从不,你可能 一直在运行模式下运行,因此采用了您不想要的优化。这两个返回语句可能已被优化器合并为一个。)更改此设置后,您将永远不会看到断点命中的行与设置它的行不同。请使用新设置仔细检查您的发现。

    如果出于某种原因您不想在调试模式下运行,还有另一种中断异常的方法(Suspend On Caught Exceptions)不受这种优化的影响。

    【讨论】:

    • 即使我只在 catch 块中的 return "" 上放置了一个断点,它仍然会在 catch 块上中断。 try 块中没有断点。
    • @Fase - 在这种情况下,我可以向你保证会返回空字符串。但是,堆栈中可能有另一个 catch 块设法重试。
    • 不返回空字符串。返回 URL 中的 json。我可以在调试器中看到 json,并且程序继续从 json 加载图像。它可以保证你的json被返回。
    • @Fase - 我相信你的报告,但 Java 不这样做。一旦抛出异常,try 块的 return 语句将永远不会执行。唯一可以胜过catch 块中的return 的是后续finally 块中的return。如果您有更多上下文(调用代码),可能会有所帮助。
    • 我知道这不应该是可能的,因为我对所有其他语言的经验。这就是为什么我感到困惑。我想我必须上传一些图片来证明这一点?
    猜你喜欢
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 2019-02-27
    • 1970-01-01
    相关资源
    最近更新 更多