使用getter时,取消引用可能会产生NullPointerException

时间:2017-04-30 09:49:46

标签: java android

我使用带有实例引用的自定义View类作为编辑器。视图仅用于片段。我需要实例引用,所以我总是可以获得自定义View的自定义参数。

public static StoryView instance;
private Story story;

public static Story getCurrentStory(){
    if(instance == null) return null;
    else return instance.story;
}

但是,当我使用此getter方法更改导航抽屉的内容时,我收到警告:

enter image description here

在这里:

private static IDrawerItem[] drawerEditorItems(){
    Story s = StoryView.getCurrentStory();
    SectionDrawerItem section_editor = new SectionDrawerItem()
         .withName(str("placeholder_story_by", s.name, s.author))
         .withDivider(false);
    return new IDrawerItem[]{ section_editor };
}

str(String id, Object... args)是一种基本格式化i18n字符串的静态方法。

我的猜测是,参考s在功能范围的末尾可能会被分配s = null?也许这可能会破坏我的自定义视图中的实际instance.story

2 个答案:

答案 0 :(得分:6)

致电时

public static Story getCurrentStory(){
    if(instance == null) return null;
    else return instance.story;
}

您检查以确保实例不为空。如果是,则返回null。这里的情况可能是实例始终为null(从未初始化)。这意味着如果要获取当前故事,必须确保在调用实例之前初始化实例。

此外,这在技术上不是必需的。返回null实例等同于检查它是否为null,然后返回null。您还可以使用@NotNull@Nullable来帮助编译器,您自己以及其他任何处理代码/与之交互的人。

此外,在某些情况下它仍可能返回null,因此您需要添加一个检查以确保它不为null。这可以使用if语句来完成:

if(s != null){
    //Do whatever
}

但是你得到这个警告的原因是(根据我的经验)几乎可以保证你会得到一个例外。以此为例:

View v = null;
v.setText("");

显示与您相同的警告。因此,最有可能的是,无论如何,您的方法都将返回null。所以你必须确保instance被初始化,并且有一个if语句以确保应用程序在它为空时不会崩溃。初始化instance是一种确保获得非空引用的方法

答案 1 :(得分:3)

这只是对可能的NPE(NullPointerException)的警告。你应该做的是在解除引用之前为s写一个空检查。那就是它。

if(s != null){
// Call to s.method();

}

最终,您必须确保在NULL时不得取消引用您的任何引用。

就个人而言,我遇到了几种在解除引用之前没有检查的情况,而且这些情况在大多数时候都是错误的。 Google开发时,Guava考虑了NPE问题,并将其纳入设计中,以确保其稳健性。