Java 防止NullPointerException警告的最佳方法?
我在Android studio中收到了这样一条警告,它告诉我: 方法调用'data.getExtras().get(“address”).toString()'可能会产生'java.lang.NullPointerException' 所以我改变了我的代码来摆脱那个警告Java 防止NullPointerException警告的最佳方法?,java,android-studio,nullpointerexception,Java,Android Studio,Nullpointerexception,我在Android studio中收到了这样一条警告,它告诉我: 方法调用'data.getExtras().get(“address”).toString()'可能会产生'java.lang.NullPointerException' 所以我改变了我的代码来摆脱那个警告 // Function to read the result from newly created activity @Override protected void onActivityResult(int requestC
// 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会在androidstudio中带回警告,而我很确定它不应该出现,因为不管它是否为null,我现在正在处理它
我的问题是,这两个解决方案中哪一个在技术上更有效,如果是try-catch解决方案,为什么Android Studio总是给我一个警告
(Android Studio 2.1.1)
更新:在尝试了多种解决方案后,我意识到android studio即使在第一个示例中也给了我一个警告,所以我仍然有这个警告,但它不再困扰我了
对于那些感兴趣的人,这里是我决定使用的新解决方案:(我仍然收到警告)
您不应该捕获
NullPointerException
——事实上,应该捕获的RuntimeException
很少
NullPointerException
表示代码存在问题,其中在方法上调用变量(或访问其字段),而引用实际具有null
值
这本质上要求检查null
值
这就是Android Studio在这种情况下似乎学究式地积极主动的地方:当然,您可以通过链接对象上的方法调用来获得NPE,如果您不能保证对象将不为null
,您应该检查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")
...
这种更改很乏味,而且会增加混乱,但只要您的方法调用没有改变任何对象(否则,只需在检查null
值之前指定一个变量),就不会影响性能
似乎有一些方法可以根据您从IDE得到的警告参数化Android Studio
请参见问题了解大致方向
注释/后期编辑
因为这是一个古老的答案,一个关于Java8的词
s旨在传达可能存在或不存在的数据的概念,例如引用对象的实例李>可选
- 换句话说,
是Optional
实例的容器,我们不确定该实例是否存在李>T
类提供了许多方法来处理这种不确定性,比繁琐地执行Optional
检查要优雅得多,有些人可能会争辩说,这比一开始就必须处理指针的概念要优雅得多,由可怕的null
指针Null
s传达李>异常
s在Java8的流中大量使用Optional
- 最后,从Oracle自己的角度来看,这是一个关于
s的良好起点Optional
- 我认为这更适合您的要求。如果您只是记录异常,那么抛出异常的代价很高
VariableType extrasX = data.getExtras();
VariableType extrasY = data.getExtras();
VariableType addressS= data.getExtras();
if(extrasX !=null && extraYs != null && addressS != null){
VariableType xType = extrasX.get("X");
VariableType yType = extrasY.get("Y");
VariableType addressType = addressS.get("address");
if(xType !=null && yType != null && addressType != null){
String sX = xType.toString();
String sY = yType.toString();
String sAddress = addressType.toString();
double dX = Double.parseDouble(sX);
double dY = Double.parseDouble(sY);
ShowSearch(dX, dY, sAddress);
} else {
Log.d("onActivityResult()", "Something went wrong, some data is
}
} else {
Log.d("onActivityResult()", "Something went wrong, some data is
}
通常,抛出异常是为了避免在不同条件下出现意外的编程错误或失败。另外,在某些情况下抛出异常可能代价高昂,所以我肯定会使用空检查(如果可能的话)
有关更多详细信息。涉及
可选对象的公认答案要求API级别为24或更高,因此我通常使用Android Studio建议在突出显示的对象周围插入对象。requirennoull()
- 它消除了警告
- 它留下了失败的可能性,即出现
NullPointerException
(这将导致更好的代码)
- 它的Android API级别低于
可选
- 它比
Optional
所需的详细得多
因此,与其检查data.getExtras().get(“x”)!=null
并忽略它为null时的潜在问题,最好使用
Objects.requirennoull(data.getExtras().get(“x”))
直接在代码中
当然,在某些情况下,您可以将其设置为null
,在这种情况下,data.getExtras().get(“x”)!=空
检查很好,导致代码忽略动作,当它是空的时候,我会相应地进行编辑。“为什么Android Studio总是在try-catch代码上给我一个警告”我能看到的唯一答案是:Android Studio没有对代码进行足够的内省来知道你正在处理它;或者说,设计预警系统的人根本不在乎你是否能处理好它。在效率方面:它起作用的几率非常、非常、非常、非常低。从维护的角度来看,做你觉得最清晰和干净的事情。在您的第一个示例中,任何合适的JIT都会很好地优化空检查(我不知道Dalvik的JIT有多好)。不确定哪一个更有效,但我不会捕获NullPointerException。当抛出NullPointerException时,应该是程序员的错误。作为一名程序员,我们确保他们不会被抛出(通过空检查)。不确定这是我个人的喜好还是被其他人广泛接受,但我个人认为捕获NullPointerException是一种不好的做法,应该尽可能避免。仍然有一些未检查的内容:getExtras()
可以返回null
。使用Intent#hasExtra(字符串名)
可以解决这个问题,idk,如果nullcheck知道的话。谢谢你提供了信息丰富的答案,我从来没有意识到用这种方式使用try-catch的缺点。然而,看看您的代码示例,检查“data!=null”不是多余的吗?检查“data.ge”不是很好吗
VariableType extrasX = data.getExtras();
VariableType extrasY = data.getExtras();
VariableType addressS= data.getExtras();
if(extrasX !=null && extraYs != null && addressS != null){
VariableType xType = extrasX.get("X");
VariableType yType = extrasY.get("Y");
VariableType addressType = addressS.get("address");
if(xType !=null && yType != null && addressType != null){
String sX = xType.toString();
String sY = yType.toString();
String sAddress = addressType.toString();
double dX = Double.parseDouble(sX);
double dY = Double.parseDouble(sY);
ShowSearch(dX, dY, sAddress);
} else {
Log.d("onActivityResult()", "Something went wrong, some data is
}
} else {
Log.d("onActivityResult()", "Something went wrong, some data is
}