包装类Integer的大坑----避坑必备

问题描述

代码例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()

猜你喜欢

转载自blog.csdn.net/GBS20200720/article/details/124382428