我的Java代码有这个(但是撇开我是否应该捕获RuntimeException不谈,我有我的理由)
catch(RuntimeException e) {
MainWindow.logger.log(Level.SEVERE, InfoMessage.MSG_MUSICBRAINZ_QUERY_SYNTAX_ERROR.getMsg(song.getRecNo(), song.getFile().getName()),e.getCause());
stats.incUnableToMatchIds();
}
我不明白为什么当异常确实发生时,它只能到达这个catch块,所以它不能确定异常发生的位置。我使用e. get原因()还是e没有区别
java.lang.NullPointerException
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:234)
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
如果我删除这个catch块,它会向我显示完整的堆栈跟踪,这就是我想要它做的,
java.lang.NullPointerException
at com.jthink.jaikoz.manipulate.classical.MusicBrainzSoundtrackChecker.updateSoundtrack(MusicBrainzSoundtrackChecker.java:37)
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:152)
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
如何使用catch中的记录器获得com. jthink.jaikoz.控制.经典.MusicBrainzSoundtrackChecker.updateSoundtrace(MusicBrainzSoundtrackChecker.java:37)线路部分?
编辑
也许正如建议的那样,这是我的记录器,因为如果我加进去
catch(RuntimeException e){e. printStackTrace();MainWindow.logger.log(Level.SEVERE,}
我得到输出确定与e. printStackTrace()
java.lang.NullPointerException
at com.jthink.jaikoz.manipulate.classical.MusicBrainzSoundtrackChecker.updateSoundtrack(MusicBrainzSoundtrackChecker.java:37)
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:152)
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
01/12/2016 11.18.53:com.jthink.jaikoz.manipulate.Analyser:waitForWorkers:WARNING: Worker:0:Exception:null
java.lang.NullPointerException
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:235)
at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
所以你有一个NPE。换句话说,你正在对一个尚未初始化(即构造)的对象调用一个方法。
有时,解决起来可能很棘手,因为未初始化的对象可以嵌套在嵌套的…对象中,并且生成此异常的方法调用可能非常远程。
这里有一个假设:如果你在没有try/catch
块的情况下没有相同的stacktrace,那么它可能是一个不同的异常。我的意思是:也许你的catch
块本身正在从与try
块不同的位置生成NPE。这是由您的日志记录行建议的:
InfoMessage.MSG_MUSICBRAINZ_QUERY_SYNTAX_ERROR.getMsg(song.getRecNo(), song.getFile().getName()),e.getCause());
那里发生了太多的事情!尝试调试这段代码,使用和不使用try/catch
,检查每个对象。我相信,在每种情况下,您都会找到不同的NPE。
更多背景,NPE不应该发生在生产代码中。你应该注意你所有的对象(和子对象)都是初始化的。
许多最近开发的语言禁止或想办法防止这个错误。
请参阅此参考:Tony Hoare,后悔null
的发明。