问题描述
代码例1
首先先贴出报错的代码:
@Test
public void test21() {
Spaces spaces = new Spaces();
// 正常构建对象spaces
spaces.setCommodityName("CommodityName");
spaces.setCommodityPrice("CommodityPrice");
spaces.setCommodityType("CommodityType");
// 此时注意spaces.getAge为空
if (spaces != null && 1 == spaces.getAge()) {
System.out.println(1);
}
// 结果:
// java.lang.NullPointerException
// at someverynbtest.Eighty.test21(Eighty.java:396)
// at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
// at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
// at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
// at java.lang.reflect.Method.invoke(Method.java:498)
// at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
// at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
// at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
// at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
// at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
// at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
// at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
// at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
// at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
// at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
// at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
// at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
// at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
// at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
// at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
// at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
// at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
// at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
// at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
// at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
}
class Spaces {
private String commodityName;
private String commodityPrice;
private String commodityType;
private Integer age;
public String getCommodityName() {
return commodityName;
}
public void setCommodityName(String commodityName) {
this.commodityName = commodityName;
}
public String getCommodityPrice() {
return commodityPrice;
}
public void setCommodityPrice(String commodityPrice) {
this.commodityPrice = commodityPrice;
}
public String getCommodityType() {
return commodityType;
}
public void setCommodityType(String commodityType) {
this.commodityType = commodityType;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
解释
Spaces对象内部的三个属性
private String commodityName;
private String commodityPrice;
private String commodityType;
均正常填充,唯独integer类型的age未填充,也就是为null
运行test21测试方法报出空指针,根据提示可以看到是在这一行
if (spaces != null && 1 == spaces.getAge()) {
System.out.println(1);
}
也就是 1 == spaces.getAge() ,这种写法有问题,难道是不能用整形数字1和null做 等于 比较吗
代码例2
再看下第二个例子:
@Test
public void test22() {
Spaces2 spaces = new Spaces2();
// 正常构建对象spaces
spaces.setCommodityName("CommodityName");
spaces.setCommodityPrice("CommodityPrice");
spaces.setCommodityType("CommodityType");
// 此时注意spaces.getAge为空
if (spaces != null && 1 == spaces.getAge()) {
System.out.println(1);
}
// 结果:(无内容)
// 代表正常,并没有报出空指针
}
class Spaces2 {
private String commodityName;
private String commodityPrice;
private String commodityType;
private int age;
public String getCommodityName() {
return commodityName;
}
public void setCommodityName(String commodityName) {
this.commodityName = commodityName;
}
public String getCommodityPrice() {
return commodityPrice;
}
public void setCommodityPrice(String commodityPrice) {
this.commodityPrice = commodityPrice;
}
public String getCommodityType() {
return commodityType;
}
public void setCommodityType(String commodityType) {
this.commodityType = commodityType;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
代码例2与例1最大的区别在于把integer类型的age替换成了int型,此时同样的测试代码没有报错。
可以得出一个结论:
int型可以与null比较(不报空指针),但是integer型不可以(会报空指针)
那么如果包装类spaces的age字段必须要用integer类型怎么办呢?
解决
代码例3
@Test
public void test23() {
Spaces spaces = new Spaces();
// 正常构建对象spaces
spaces.setCommodityName("CommodityName");
spaces.setCommodityPrice("CommodityPrice");
spaces.setCommodityType("CommodityType");
// 此时注意spaces.getAge为空
if (spaces != null && spaces.getAge() != null && 1 == spaces.getAge()) {
System.out.println(1);
}
// 结果:(无内容)
// 代表正常,并没有报出空指针
}
此处使用的spaces仍然是integer类型的版本,没有报出空指针,那么其实只要在判断age值之前,再加一个判空操作即可了
spaces != null && spaces.getAge() != null && 1 == spaces.getAge()
结论
对不知是否为null的integer类型值进行判断时(默认认为该integer类型的成员在另一po类中),需要三个条件并行:
例:
spaces != null && spaces.getAge() != null && 1 == spaces.getAge()
对不知是否为null的int类型值进行判断时(默认认为该int类型的成员在另一po类中),只需要两个条件并行:
例:
spaces != null && 1 == spaces.getAge()