找出以编程方式抛出NullPointerException的变量
我知道我可以使用这些技术找出Java中的变量是否为null:
- if
(var==null)
– >工作太多了 -
try { ... } catch (NullPointerException e) { ...}
– >它告诉我什么行抛出exception - 使用调试器 – >手动,太慢了
考虑以下代码行:
if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0) {
我想知道是否有一种通用的方法来以编程方式找出哪个变量(不仅仅是行)在某个代码区域中抛出NullPointerException。 在这个例子中,知道这一点
因为即使没有涉及变量也可能导致空指针exception:
throw new NullPointerException();
我不得不说,没有通用的方法可以将空指针exception固定到特定变量。
你最好的选择是尽可能少地在每一行上添加语句,以便明显导致空指针exception的原因。 考虑在问题中重构代码,看起来像这样:
List items = this.superSL.items; String name = items.get(name); String source = name.getSource(); if (source.compareTo(VIsualShoppingList.Source_EXTRA) == 0) { // ... }
这是更多的代码行。 但它也更具可读性和可维护性。
抱歉,不,没有一种简单的编程方式来确定哪个变量或方法调用是exception的来源。 您可以使用类似面向方面编程(AOP)之类的东西 ,例如AspectJ ,但这不是语言所固有的,并且通常不会仅仅为了调试目的而合并到程序中。
-
if (var==null) -> too much work
-
try { } catch() { }
-
Debugger
我知道你不想听到这个,但这些只是做生意的成本。
if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0) {
看到如此多的串联方法调用是不寻常的。 我相信你最好的选择是养成更多打破这些的习惯 – 每行只需要1个电话,但不会少于此。 为什么?
1) Correctness
– 在这些调用之一的设计中它是否有效返回null? 如果是这样,你应该将其分解,测试并适当地处理它。
2)可理解性 – 未来的维护者(包括将来你 )将更容易理解你是否有中间的,命名良好的变量来帮助澄清这一行上发生的事情。
3) Efficiency
– 通常当你深入到图形中(将一系列方法调用串联起来)时,你可能需要稍后回到那里。 在中间变量中捕获此中间值意味着避免再次进行一个或多个方法调用。
4) Debugging
– 如你的问题所示,将这样的复杂线路分开可以简化调试。 通过缩小exception的可能来源。
“使用调试器 – >手动,太慢”是什么意思? 如果您的代码结构合理,那么在同一行上使用的变量不会超过两个或三个。 检查它们是否太慢了? 你每分钟都没有NullPointers。
我知道你提出(var==null)
是太多的工作,但是,正如Miguel在评论中所说,这就是我想要的。
我想你应该注意到Demeter Law 。
严格遵循它的人并不多,因为它导致了很多委托方法。
但是离它太远将导致对内部结构的依赖,这应该是透明的。
不幸的是,Java不会向您显示变量的名称或除行号之外的错误的确切位置。 如果您使用Eclipse,则可以使用可为空的注释,例如,请参阅http://www.fosslc.org/drupal/content/bye-bye-npe 。 请参阅我应该使用哪个@NotNull Java注释? 用于其他注释系统。
对我来说真正有效的方法是捕获通常被抛出的exception,然后使用Log查看它们中是否有任何“null”值。
我的代码:
try { if (description_visible) advice_title_cur.setText(all_title_array[pos]); else advice_title_cur.setText(all_title_array[pos] + "..."); } catch (NullPointerException e) { e.printStackTrace(); Log.e("My name", "description_visible " + description_visible); Log.e("My name", "advice_title_cur " + advice_title_cur); Log.e("My name", "all_title_array " + all_title_array); Log.e("My name", "pos " + pos); }