java – 防止NullPointerException警告的最佳方法?

我在Android工作室发出了这个警告,告诉我:

Method invocation ‘data.getExtras().get(“address”).toString()’ may produce ‘java.lang.NullPointerException’

所以我改变了我的代码以摆脱那个警告.

// Function to read the result from newly created activity
@Override
protected void onActivityResult(int requestCode,
                                int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == 100 && data.getExtras().get("x") != null &&
            data.getExtras().get("y") != null && data.getExtras().get("address") != null) {
        String sX = data.getExtras().get("x").toString();
        String sY = data.getExtras().get("y").toString();
        String sAddress = data.getExtras().get("address").toString();
        double dX = Double.parseDouble(sX);
        double dY = Double.parseDouble(sY);
        ShowSearch(dX, dY, sAddress);
    }
    else{
        Log.d("onActivityResult()", "Something went wrong, either the result code is wrong or the data is null");
    }
}

然后在第二个想法,我选择了尝试捕获.

// Function to read the result from newly created activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == 100) {
        try {
            String sX = data.getExtras().get("x").toString();
            String sY = data.getExtras().get("y").toString();
            String sAddress = data.getExtras().get("address").toString();
            double dX = Double.parseDouble(sX);
            double dY = Double.parseDouble(sY);
            ShowSearch(dX, dY, sAddress);
        } catch (java.lang.NullPointerException e){
            Log.d("onActivityResult()", "Something went wrong, some data is null");
        }
    }
}

但是使用try catch会在android-studio中收回警告,因为我很确定它不应该因为它是否为null,我现在正在处理它.

这是我的问题,两个解决方案中的哪一个在技术上更有效,如果它是尝试捕获解决方案为什么Android Studio会不断给我一个警告?

(Android Studio 2.1.1)

更新:尝试了多个解决方案之后,我意识到android studio甚至在第一个例子中给了我一个警告,所以我仍然有这个警告,但它不再困扰我了.

对于那些感兴趣的人,我决定使用新的解决方案:(我仍然收到警告)

// Function to read the result from newly created activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == 100 && data != null) {
        if (data.hasExtra("x") && data.hasExtra("y")
                && data.hasExtra("address")) {
            if (data.getExtras().get("x") != null && data.getExtras().get("y") != null
                    && data.getExtras().get("address") != null) {
                String sX = data.getExtras().get("x").toString();
                String sY = data.getExtras().get("y").toString();
                String sAddress = data.getExtras().get("address").toString();
                double dX = Double.parseDouble(sX);
                double dY = Double.parseDouble(sY);
                ShowSearch(dX, dY, sAddress);
            } else {
                Toast.makeText(this, "Error in location", Toast.LENGTH_SHORT).show();
                Log.d("onActivityResult()", "Something went wrong, some extra data is null");
            }
        } else {
            Toast.makeText(this, "Error in location", Toast.LENGTH_SHORT).show();
            Log.d("onActivityResult()", "Something went wrong, some extra data doesn't exist");
        }
    } else{
        Toast.makeText(this, "No Location found", Toast.LENGTH_SHORT).show();
        Log.d("onActivityResult()", "Something went wrong, either the result code is wrong or the data is null");
    }
}

解决方法:

你不应该捕获NullPointerException – 事实上应该捕获很少的RuntimeExceptions.

NullPointerException表示代码存在问题,其中变量是在(或访问其字段)时调用的方法,而引用实际上具有空值.

这基本上要求检查空值.

这就是Android Studio在这种情况下似乎迂回主动的地方:当然你可以通过链接对象的方法调用来获得NPE,如果你不能保证对象不是null,你应该检查空值.

例如:

if (resultCode == 100 
    && data.getExtras().get("x") != null 
    && data.getExtras().get("y") != null 
    && data.getExtras().get("address") != null) { ...

…会变得乏味:

if (resultCode == 100 
    && data != null // unlikely
    && data.getExtras() != null
    && data.getExtras().get("x") != null 
    ...

……或者更确切地说,在这种情况下:

if (resultCode == 100 
    && data != null // unlikely
    && data.hasExtra("x")
    ...

这种变化很乏味并且增加了混乱,但只要您的方法调用不会改变任何对象(否则,只需在检查空值之前分配给变量),就性能而言几乎不重要.

似乎有一些方法可以根据您从IDE获得的警告来参数化Android Studio.

有关总体方向,请参阅this问题.

注意/延迟编辑

这是一个古老的答案,关于Java 8的Optional.

>可选项旨在传达可能存在或不存在的数据概念,例如引用对象的实例.
>换句话说,可选< T>是一个T实例的容器,它的存在我们不确定.
>可选类具有许多方法来处理这种不确定性,而不是繁琐地执行空检查,或者有些人可能会争辩,而不是必须首先处理指针的概念,如前所述.可怕的NullPointerExceptions.
>在Java 8的流API中大量使用了可选项.
>最后,从Oracle自己的角度来看,here是Optionals的一个很好的起点.

上一篇:尝试在空对象引用上调用虚方法’java.lang.String android.content.Context.getPackageName()’


下一篇:Drawable的mutate方法Android 1.6中的NullPointerException