java三目运算符的一些实践和困惑

whithorse 2014-06-27 11:31:08
同事使用三木运算符遇到的问题,我测试了一下也很困惑,废话不多说,上代码:

版本一:

package com.test.Calendar;

public class AClass {

private Integer a;

public Integer getA() {
return a;
}

public void setA(Integer a) {
this.a = a;
}

}

package com.test.Calendar;

import java.util.HashMap;
import java.util.Map;

public class TestInteger {

public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
AClass a = new AClass();
Integer test = map.get("d")== null ? a.getA() : 3 ;
System.out.println(test);
}

}


问题来了,第27行,空指针异常,debug一下,a.getA()返回的是null,赋值null不行?

版本2:
更改三木运算符那一行:
改成:

package com.test.Calendar;

import java.util.HashMap;
import java.util.Map;

public class TestInteger {

public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
AClass a = new AClass();
Integer test = map.get("d")== null ? null : 3 ;
System.out.println(test);
}

}

通过

版本三:


package com.test.Calendar;

import java.util.HashMap;
import java.util.Map;

public class TestInteger {

public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
AClass a = new AClass();
Integer test = map.get("d")== null ? a.getA() : (Integer)3 ;
System.out.println(test);
}

}


通过,到这里我已经怀疑是三目运算符后面两个表达式的类型一定要一样

于是,版本四:
把A的私有变量,改成int型

package com.test.Calendar;

public class AClass {

private int a;

public int getA() {
return a;
}

public void setA(int a) {
this.a = a;
}

}

package com.test.Calendar;

import java.util.HashMap;
import java.util.Map;

public class TestInteger {

public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
AClass a = new AClass();
Integer test = map.get("d")== null ? a.getA() : 3 ;
System.out.println(test);
}

}


通过

可是问题又来了,看版本五:
给A的私有变量a赋初始值1,这时就算类型不一样也可以通过

package com.test.Calendar;

public class AClass {

private Integer a =1;

public Integer getA() {
return a;
}

public void setA(Integer a) {
this.a = a;
}

}

package com.test.Calendar;

import java.util.HashMap;
import java.util.Map;

public class TestInteger {

public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
AClass a = new AClass();
Integer test = map.get("d")== null ? a.getA() : 3 ;
System.out.println(test);
}

}



最后,我的理解:肯定是跟空类型时候的内存分配和类型之间的自动转换以及三目运算符的执行顺序有关,但不能理解透彻,望各位高手解答

附版本六:
if/else方式

package com.test.Calendar;

public class AClass {

private Integer a;

public Integer getA() {
return a;
}

public void setA(Integer a) {
this.a = a;
}

}

package com.test.Calendar;

import java.util.HashMap;
import java.util.Map;

public class TestInteger {

public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
AClass a = new AClass();
Integer test = null;
if (map.get("d")== null) {
test = a.getA();
}else {
test = 3;
}
System.out.println(test);
}

}



通过,没问题,所以,三目运算符底层实现和if/else肯定还是不一样的

各位大神,帮忙解释一下,希望能透彻点,就是为null和不为null的区别,以及int和Integer的转换
...全文
1176 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
背西风酒旗 2016-09-20
  • 打赏
  • 举报
回复
3的博文说的太好了
Lbj_king 2016-09-20
  • 打赏
  • 举报
回复
要确保a不为null才行。 三元运算首先要得到真值跟假值,然后对结果进行判断赋值的。
业余草 2014-06-27
  • 打赏
  • 举报
回复
引用 3 楼 magi1201 的回复:
遇到包装类型的计算操作,三目运算符会自己进行拆箱操作 Java自动装/拆箱下,三目运算符的潜规则
这一个是唯一正确的解释 遇到包装类型的计算操作,三目运算符会自己进行拆箱操作
whos2002110 2014-06-27
  • 打赏
  • 举报
回复
不管getA()是返回Integer还是int, 当map.get("d")== null ? a.getA() : 3 ;是表达式的结果一定是个int类型,这在编译器就已经确定了, 这就是为什么会跑nullPointerException,而不是编译不通过。 而map.get("d")== null ? null : 3 ; 的返回确实Integer类型。 记住,三目运算中第二个和第三个表达式一定返回相同类型。你这里无外乎是自动装箱拆箱的问题,其实不用过分纠结。
姜小白- 2014-06-27
  • 打赏
  • 举报
回复
遇到包装类型的计算操作,三目运算符会自己进行拆箱操作 Java自动装/拆箱下,三目运算符的潜规则
whithorse 2014-06-27
  • 打赏
  • 举报
回复
引用 1 楼 JUST_lOVE_LE 的回复:
Integer 是一个类 int 是一个类型 一个是 Integer test 一个是 AClass a 你让 test = a 明显不行嘛
麻烦认真点,看版本四,int是可以自动转换为Integer的,这是java的自动转换机制
北落师门_Orz 2014-06-27
  • 打赏
  • 举报
回复
Integer 是一个类 int 是一个类型 一个是 Integer test 一个是 AClass a 你让 test = a 明显不行嘛
只是_曾经 2014-06-27
  • 打赏
  • 举报
回复
引用 4 楼 whos2002110 的回复:
不管getA()是返回Integer还是int, 当map.get("d")== null ? a.getA() : 3 ;是表达式的结果一定是个int类型,这在编译器就已经确定了, 这就是为什么会跑nullPointerException,而不是编译不通过。 而map.get("d")== null ? null : 3 ; 的返回确实Integer类型。 记住,三目运算中第二个和第三个表达式一定返回相同类型。你这里无外乎是自动装箱拆箱的问题,其实不用过分纠结。
学习了!
whithorse 2014-06-27
  • 打赏
  • 举报
回复
引用 6 楼 dcxy0 的回复:
可用.

 
import java.util.HashMap;
import java.util.Map;

class AClass {
     
    private Integer a;
    
    private int numb;
    
    
    public void setNumb(int numb)
    {
    	 this.numb=numb;
    }
    
    public int getNumb()
    {
    	return numb;
    }
    
 
    public Integer getA() {
        return a;
    }
 
    public void setA(Integer a) {
        this.a = a;
    }
 
}
 

 

 
public class NumberTest {
     
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<String, Object>();
        AClass a = new AClass();
        a.setA(40);//在这里设置值,当你去取的时候就不会是空的了.
        a.setNumb('a');//
        /*
         	当你用Integer来接收三目运算的值时,你就只能返回int或Integer或者能隐式转换为int(Integer)类型的值.
         */
        Integer test = (map.get("d")!= null) ? a.getA() : 'a';
        System.out.println(test);
    }
     
}
你可能理解错了我的意思,我知道你这样可用,我问的是为什么直接赋值为null就可以,但是用三目运算符中的对象来get却不行,不过谢谢你的回答,三楼和五楼已经解答了,我用反编译工具看了class文件,确实如那篇博文所说
JPF1024 2014-06-27
  • 打赏
  • 举报
回复
可用.

 
import java.util.HashMap;
import java.util.Map;

class AClass {
     
    private Integer a;
    
    private int numb;
    
    
    public void setNumb(int numb)
    {
    	 this.numb=numb;
    }
    
    public int getNumb()
    {
    	return numb;
    }
    
 
    public Integer getA() {
        return a;
    }
 
    public void setA(Integer a) {
        this.a = a;
    }
 
}
 

 

 
public class NumberTest {
     
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<String, Object>();
        AClass a = new AClass();
        a.setA(40);//在这里设置值,当你去取的时候就不会是空的了.
        a.setNumb('a');//
        /*
         	当你用Integer来接收三目运算的值时,你就只能返回int或Integer或者能隐式转换为int(Integer)类型的值.
         */
        Integer test = (map.get("d")!= null) ? a.getA() : 'a';
        System.out.println(test);
    }
     
}

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧