2009-06-08 77 views
22

考虑这条线:摆好避免NullPointerException异常在Java中

if (object.getAttribute("someAttr").equals("true")) { // .... 

显然,这条线是一个潜在的漏洞,该属性可能是null,我们会得到一个NullPointerException。因此,我们需要把它重构为两个选择:

第一种选择:

if ("true".equals(object.getAttribute("someAttr"))) { // .... 

第二个选项:

String attr = object.getAttribute("someAttr"); 
if (attr != null) { 
    if (attr.equals("true")) { // .... 

第一个选项是尴尬的阅读,但更简洁,而第二个意图明确,但详细。

在可读性方面,您更喜欢哪个选项?

回答

27

我一直使用

if ("true".equals(object.getAttribute("someAttr"))) { // .... 

因为它虽然是一个小更难以读懂它的详细得多,我认为这是足够的可阅读,所以你习惯它很容易

+3

我甚至不认为这是更难以阅读的IMPL。 – 2009-06-08 11:52:02

1

我喜欢选项1,我会认为它足够可读。

选项3 btw将引入getAttribute方法,该方法将默认值作为参数。

+0

这个问题是关于'如果'块,所以关于你的选择3:“你不能总是依靠该方法将永远不会返回空值 – 2009-06-08 09:02:26

+0

当然,您可以确保它永远不会返回null作为默认值。 – willcodejavaforfood 2009-06-08 09:05:11

+0

选项3将全部关于将错误处理和空检查移动到根据DRY的方法 – willcodejavaforfood 2009-06-08 09:05:47

0

Util.isEmpty(string) - 返回string == null || string.trim().isEmpty() Util.notNull(string)返回“”if if string == null,否则为字符串。 Util.isNotEmpty(string)退货! Util.isEmpty(string)

而且我们有一个约定,对于字符串,Util.isEmpty(string)在语义上意味着为真,而Util.isNotEmpty(string)在语义上意味着假。

17

在第二个选项,你可以采取的短路&&优势:

String attr = object.getAttribute("someAttr"); 
if (attr != null && attr.equals("true")) { // .... 
1

总是向往更短的代码,因为两者都是functionaly等同。特别是在这种情况下,可读性不会被牺牲。

2

在某些情况下,简洁的方法感觉不对头开始,但有效变成惯用。这是其中之一;另一个是这样的:

String line; 
while ((line = bufferedReader.readLine()) != null) { 
    // Use line 
} 

在一个条件的副作用?不可想象的!除了它比替代品更好的时候,当你认识到特定的模式。

这种模式很相似 - 在Java中这很常见,我希望任何经验丰富的开发人员都能认识到这一点。结果是令人愉快的简洁。 (有趣的是,我有时会看到使用相同习惯用法的C#代码,不必要地 - 平等运算符可以很好地处理C#中的字符串。)

底线:使用第一个版本,并熟悉它。

0

这是一个非常好的问题。 我通常用并不擅长:

if (object.getAttribute("someAttr") != null && object.getAttribute("someAttr").equals("true")) { // .... 

(我不会再使用它)

0

我有另外一个答案;

List<Map<String, Object>> group = jjDatabase.separateRow(db.Select("SELECT * FROM access_user_group WHERE user_id=1 ;")); 

没有 “group_c80” 在我的数据库 'access_user_group' 一栏,所以在GET(0)获得( “group_c80”)空指针异常协定。但我处理它通过下面的代码:

for (int j = 1; j < 100; j++) { 
        String rulId="0";//defult value,to privent null pointer exeption in group_c 
        try { 
         rulId = group.get(0).get("group_c" + j)).toString(); 
        } catch (Exception ex) { 
         ServerLog.Print("Handeled error in database for " + "group_c" + (j < 10 ? "0" + j : j) +"This error handeled and mot efect in program"); 
         rulId = "0"; 
        }} 
0

这里是我的方法,需要一个PropertyUtil类,但是,但它只能写一次:

/** 
* Generic method to encapsulate type casting and preventing nullPointers. 
* 
* @param <T>   The Type expected from the result value. 
* @param o   The object to cast. 
* @param typedDefault The default value, should be of Type T. 
* 
* @return Type casted o, of default. 
*/ 
public static <T> T getOrDefault (Object o, T typedDefault) { 
    if (null == o) { 
     return typedDefault; 
    } 
    return (T) o; 
} 

客户端代码可以做到这一点:

PropertyUtil.getOrDefault(obj.getAttribute("someAttr"), "").equals("true"); 

或者,对于一个列表:

PropertyUtil.getOrDefault(
    genericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST 
).contains(element); 

,还是列出的消费者,这将拒绝对象:

consumeOnlyList(
    PropertyUtil.getOrDefault(
     enericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST 
    ) 
) 

默认可能是空对象模式https://en.wikipedia.org/wiki/Null_Object_pattern