我正在创建Android应用程序,在使用try-finally bock时,会发生一些与处理异常相关的奇怪行为。
为什么下面代码的输出是NullPointerException而不是SocketTimeoutException
consumeSomeService();
[...]
private void consumeSomeService() {
try {
getResponse();
} catch (SocketTimeoutException ste) {
Log.d("tag", "SocketTimeoutException");
} catch (Exception e) {
Log.d("tag", e.getClass().getName());
}
}
private static void getResponse() throws SocketTimeoutException {
try {
throw new SocketTimeoutException();
} finally {
Log.d("tag", "finally!"); // No matter what is here, always throw NullPointerException
}
}如果删除finally块,它将按预期工作。
PC/台式机上的相同代码会正确地生成SocketTimeoutException。
编辑:堆栈跟踪,其中"MyActivity.java:38“始终是finally块中的最后一行。
java.lang.NullPointerException
at mycompany.exceptiontest.MyActivity.getResponse(MyActivity.java:38)
at mycompany.exceptiontest.MyActivity.consumeSomeService(MyActivity.java:21)
at mycompany.exceptiontest.MyActivity.onCreate(MyActivity.java:16)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)发布于 2014-10-16 22:30:25
正在将注释转换为答案以提供更多空间...
下面是一些基本的想法,它们测试了我们对正在发生的事情的所有假设。
我认为GenyMotion运行的是真正的安卓系统,所以我认为它应该和这款设备运行的一样。
在运行4.4.4的实际Nexus 7上进行了测试,结果与预期相符。
通过放入一些不可能抛出空指针异常的代码来测试finally。
private static void getResponse() throws SocketTimeoutException {
try {
throw new SocketTimeoutException();
} finally {
int i = 1;
if (i==1) {i++;}
}
}看看在这种情况下哪一行出现了问题,这将是很有趣的。
通过抛出其他东西来测试SocketTimeoutException的问题。
private void consumeSomeService() {
try {
getResponse();
} catch (Exception e) {
Log.d("tag", e.getClass().getName());
}
}
private static void getResponse() throws Exception {
try {
throw new Exception();
} finally {
Log.d("tag", "finally!");
}
}有趣的是,可以通过内联方法getResponse()来测试行为。
private void consumeSomeService() {
try {
throw new SocketTimeoutException();
} catch (SocketTimeoutException ste) {
Log.d("tag", "SocketTimeoutException");
} catch (Exception e) {
Log.d("tag", e.getClass().getName());
} finally {
Log.d("tag", "finally!");
}
}https://stackoverflow.com/questions/26405054
复制相似问题