处理空指针异常的最佳模式

时间:2016-11-26 12:23:16

标签: java android nullpointerexception gson

我正在寻找处理 NPE(空指针异常)的最佳模式。 我正在使用web api调用的改造,但有时可能有些字段可能为null,或者也可能是null数组的机会。 我在寻找什么,有没有办法只处理一次?。

E.g。

模型类

public class ModelClass{
     String name;
     String email;
     List<Items> items;
}

JSON文件

{
  name:null,
  email:"NPE@jvm.com",
Items:[]
}

所以在反序列化json 文件后,当我尝试 setText到textview object.getName()时将通过 NPE

我有 非常大的模型类集合 ,实际上将每个字段放在 try {} catch()中是错误的使用它。 有没有更好的方法来处理这种情况?。

5 个答案:

答案 0 :(得分:1)

我会把它包裹在Optional附近。这将迫使您在编译时决定如果值为null,该怎么做。

Optional<String> optionalName = Optional.ofNullable(person.getName());

然后您可以决定,例如:

  • 指定默认值:String name = optionalName.orElse("Bob");
  • 您选择的例外:String name = optionalName.orElseThrow(() -> new IllegalArgumentException("Invalid name"));

答案 1 :(得分:0)

使用Gson库反序列化你的json文件,它通过调用serializeNulls来处理null项。

这是Gson图书馆的一个很好的指南(谷歌): https://futurestud.io/tutorials/gson-getting-started-with-java-json-serialization-deserialization

答案 2 :(得分:0)

如果你只是想避免NPE,因为你觉得讨厌,你可以在自己反序列化json文件时初始值。例如,如果反序列化的名称为null,则只需要init name =“”。有了这个,您不必触及所有模型类,只需修改反序列化方法即可。这可以防止NPE。

答案 3 :(得分:0)

我不建议你在一个地方这样做。最好的方法是在使用该字段之前检查null,否则像gson这样的lib会为你做这个。并且将所有空字符串替换为&#34;&#34;并不高效和优雅。因为json字符串可能具有深层次结构。因此,如果@ myoldgrandpa的答案可行,那么如果您坚持这样做,这可能是最佳方式。

答案 4 :(得分:-1)

首先,您应该使用encapsulation。这意味着变量应为private/protected并且具有公开getterssetters

像这样:

public class ModelClass{
    private String name;
    private String email;
    private List<Items> items;
    public ModelClass(){
        items = new List<Items>();
    }
    public String getName(){
        return name != null?name:"";
    }
    public void setName(String name){
        this.name = name;
    }
    public String getEmail(){
        return email=null?email:"";
    }
    public void setEmail(String email){
        this.email= email;
    }
    public Items getItem(int index){
        return items!=null?items.get(index):null;
    }
    public boolean addItem(Items item){
        return items!=null?items.add(item):false;
    }
}

正如您所看到的,list现在将在constructor中初始化。因此,外部类只能添加或获取Items。如果列表为空,那么getteradder将分别返回null和false,而不是抛出NPE。基本上当您使用serializationdeserialization时,您应该初始化Objects内的所有Stringsconstructor除外)。基本上如果field有可能为null,那么你应该检查。

同样根据Java Naming Conventions,您应该将Items class: Item命名为Classes,如果持有一组项目,则{name}只能为复数。例如:

public class Item{
     private String field;
     public Item(){
          field = "hello";
     }
}

public class Items{
     private List<Item> items;
     public Items(){
          items = new List<Item>();
     }
}

最后,我还建议您查看String方法:valueOf。正如您所看到的,该方法检查传递的变量是否为null,并且仅在不是时才返回字符串value。你可以使用类似的东西。