简体   繁体   English

Java执行'catch'块没有错误,并且仍以某种方式运行'try'块

[英]Java executes 'catch' block with no error, and somehow still runs 'try' block

I have a problem with the following code. 我有以下代码的问题。 First, I am a newbie to Java with experience with several other languages. 首先,我是Java的新手,拥有其他几种语言的经验。

When I run the following on Android, it errors at "in.close();", jumps to the catch block and runs Return ""; 当我在Android上运行以下命令时,它在“in.close();”中出错,跳转到catch块并运行Return“”; The thing is, the function doesn't return an empty string, it successfully returns the correct json data even though the debugger says it isn't running return json, but that it's running return ""; 问题是,该函数不返回空字符串,它成功返回正确的json数据,即使调试器说它没有运行return json,但它正在运行返回“”;

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!
    }
}

I copy the exact same code into a Java console so that I can output the error message and watch it in the debugger with break points, and the code executes without error. 我将完全相同的代码复制到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());
}   

What exactly is going on? 到底发生了什么? Why is my code run on Android erroring when it runs in a Java Console just fine? 为什么我的代码在Android控制台上运行时在Android上运行错误就好了? Why when it errors does it not return what the error is supposed to return; 为什么当它出错时它不会返回错误应该返回的内容; and empty string? 和空字符串? How can I view the error message in Android? 如何在Android中查看错误消息?

You should make sure to include the 你应该确保包括

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

permission in your androidManifext.xml . androidManifext.xml权限。

You are trying to retrieve data from a remote location. 您正在尝试从远程位置检索数据。 On Java console you can do it without such permissions, but not in Android. 在Java控制台上,您可以在没有此类权限的情况下执

Forget about "System.out.println" in Android. 忘掉Android中的“System.out.println”。 You can use "Logcat" view in Eclipse. 您可以在Eclipse中使用“Logcat”视图。 This is used to show every log you want from your device. 这用于显示您希望从设备中获取的每个日志。 Also, you can replace " System.out.println(json); " by " Log.e("MyApp", "Here is my Json: '"+json+"'"); " and you'll see your json in the logcat... ;) 此外,您可以将“ System.out.println(json); ”替换为“ Log.e("MyApp", "Here is my Json: '"+json+"'"); ”并且您将看到您的json in logcat ...;)

About your exception, you have a method in the frameworkthat automatically logs the exceptions in the logcat: " myException.printStackTrace(); " 关于你的异常,你在框架中有一个方法可以自动记录logcat中的异常:“ myException.printStackTrace();

A Reader reads text, an InputStream binary data. Reader读取文本,InputStream二进制数据。 The bridge InputStreamReader needs a character encoding, and takes in your case the default OS encoding. 桥InputStreamReader需要一个字符编码,并在您的情况下采用默认的OS编码。

So better explicitly use an encoding: 所以更好地明确使用编码:

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

As JSON should better be in UTF-8, I have given that. 由于JSON应该更好地采用UTF-8,我已经给出了。 But the default encoding on Android is UTF-8 and with you probably Cp1252. 但Android上的默认编码是UTF-8,可能还有Cp1252。 So there might be something else wrong too. 所以可能还有其他错误。

Your code appears to be correct. 您的代码似乎是正确的。 If you did see a JSON returned, then you were not getting any IOException from close . 如果您确实看到返回了JSON,那么您没有从close获得任何IOException

Edit : 编辑

Your updated source code clearly shows that there is no return from finally or retry logic in play here. 您更新的源代码清楚地表明此处没有来自finally或重试逻辑的返回。 Good. 好。

Visit the following setting in your environment: Window / Preferences / Run/Debug / Launching / "Launch in debug mode when workspace contains breakpoints" 访问您环境中的以下设置:Window / Preferences / Run / Debug / Launching /“当工作空间包含断点时以调试模式启动”

Set this to Always or Prompt . 将其设置为“ 始终”或“ 提示” (If it was previously Never , you might have been running in Run mode, thus employing optimizations you did not want. The two return statements may have been combined into one by the optimizer.) After you change this setting, you should never see a breakpoint hit at a line different from the line on which it was set. (如果以前是Never ,那么你可能一直在运行模式下运行,因此采用了你不想要的优化。优化器可能将两个return语句组合成一个。)更改此设置后,你永远不应该看到断点在与其设置的行不同的行上。 Please double check your findings with the new setting. 请使用新设置仔细检查您的发现。

There is also an alternate way of breaking on exceptions (Suspend On Caught Exceptions) that is immune to this kind of optimization, if for any reason you do not want to run in debug mode. 如果由于任何原因您不想在调试模式下运行,还有一种可以打破异常(Suspend On Caught Exceptions)的替代方法,这种方式不受此类优化的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM