A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 我是菜鸟 于 2013-1-21 15:37 编辑

public static void main(String[] args)
{
        Map<String, Integer> map = new HashMap<String, Integer>();
        String str = "x";
        Integer i = Math.random()*10 > 7? 5 : null;
        System.out.println(i);


        map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));
}

这段代码会报NullPointerException,看看哪位能找出来并说出原因


=============================================================================


HashMap<String, Integer>
map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));

在编译时期就要确定表达式的类型
i==null? 1 : i,表达式2和3分别是int和Integer,该语句的返回类型是int,可以推出表达式3也就是 (map.get(str) + (i==null? 1 : i))的返回类型为int
可以看作:
map.get(str)==null ? Integer : int,所以当i=5的时候,i可以正常拆箱,但当i=null,拆箱的时候调用null.intValue(),就会报空指针异常

验证:
map.put(str, map.get(str)==null ? 1 : (map.get(str) + (i==null? 1 : i)));
把i改成常量,保证表达式2类型为int,这时无论i等于什么,程序都正常,可以说明问题就出在表达式2的拆箱


所以在使用三元运算符,如果:两边表达式的类型不一致,最好做显式强制类型
map.put(str, map.get(str)==null ? i : (Integer)(map.get(str) + (i==null? 1 : i)));

*如果有问题或疑问,请指出,谢谢














点评

赶紧申请改名啊 准备申请入学测试了  发表于 2013-1-21 13:57

评分

参与人数 2技术分 +1 黑马币 +12 收起 理由
Rancho_Gump + 1 赞一个!
黄锦成 + 12 鼓励一下

查看全部评分

48 个回复

倒序浏览
本帖最后由 王少雷 于 2013-1-20 23:18 编辑

我不得不承认楼主灰常有才。~~~~
这张图应该能说明问题吧
其实程序在这里Integer i = Math.random()*10 > 7? 5 : null;我就觉得不对劲
1个NULL 下面不用走了全是NULL
回复 使用道具 举报
本帖最后由 黑马刘杰 于 2013-1-20 22:37 编辑

map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i))如果i为null这里的map.get(str)==null?i 就是null,所以后面的
(map.get(str) + (i==null? 1 : i))还会执行,而null+1就会报异常。

评分

参与人数 1黑马币 +12 收起 理由
黄锦成 + 12

查看全部评分

回复 使用道具 举报
问题应该是出在最后一句,我们的目的是把键值对放入集合中,也就是说集合中现在还没有这个键值对~~~那么此时再调用map.get(),根据键取值当然会出现这个异常了~~~
回复 使用道具 举报
王少雷 发表于 2013-1-20 22:34
我不得不承认楼主灰常有才。~~~~
这张图应该能说明问题吧
其实程序在这里Integer i = Math.random()*10 > 7 ...

就算Integer i = null,下面还会继续走了,请验证
回复 使用道具 举报
黑马刘杰 发表于 2013-1-20 22:36
map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i))如果i为null这里的map.get(str)==null?i 就是 ...

null+1不是报异常,是直接err
回复 使用道具 举报
王晓斌 发表于 2013-1-20 22:39
问题应该是出在最后一句,我们的目的是把键值对放入集合中,也就是说集合中现在还没有这个键值对~~~那么 ...

Map<String, Integer> map = new HashMap<String, Integer>();
String str = "x";
System.out.println(map.get(str));

就算没有操作put,还是可以操作get的,请验证
回复 使用道具 举报
本帖最后由 柴乔军 于 2013-1-20 23:09 编辑


楼主的程序要么输出5;要么就会报空指针,如果是空指针的话,应该是图中画红圈的i造成的吧,楼主对么?
i是一个null,不是Integer对象

点评

主要是后面那里出错了。get出来的是null ,此时null + 1或是5,就运算出错  发表于 2013-1-20 23:49
回复 使用道具 举报
本帖最后由 王少雷 于 2013-1-20 23:18 编辑

我是菜鸟 发表于 2013-1-20 22:50
就算Integer i = null,下面还会继续走了,请验证

是的~,,,莫非是NULL被随机了
回复 使用道具 举报
柴乔军 发表于 2013-1-20 23:06
楼主的程序要么输出5;要么就会报空指针,如果是空指针的话,应该是图中画红圈的i造成的吧,楼主对么?
i ...

不对,请再验证
回复 使用道具 举报
txl 中级黑马 2013-1-20 23:20:01
11#
我也想了很久这个题,根据判断楼上指出问题出处应该是对的,我想jvm可能会调用Integer.intValue()方法或者是Integer中其他方法,但i为null,所以报异常,但直接写 map.put(str,null);不会报错,我真的就黔驴技穷了...
回复 使用道具 举报
我是菜鸟 发表于 2013-1-20 23:10
不对,请再验证

i==null? 1 : i
这句话出现的空指针,==判断报出来的i为null;
  1. public class Test1 {
  2.        
  3.         public static void main(String[] args)
  4.     {
  5.             Map<String, Integer> map = new HashMap<String, Integer>();
  6.             String str = "x";
  7.             //Integer i = Math.random()*10 > 7? 5 : null;
  8.             Integer i = 5;
  9.             System.out.println(map.get(str));
  10.             System.out.println(map.get(str) + (i==null? 1 : i));
  11.             System.out.println(map.get(str));
  12.             System.out.println(i);


  13.             map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));
  14.     }


  15. }
  16. 结果:
  17. null
  18. Exception in thread "main" java.lang.NullPointerException
  19.         at test.Test1.main(Test1.java:15)

复制代码
回复 使用道具 举报
王少雷 发表于 2013-1-20 23:10
我是菜鸟 发表于 2013-1-20 22:50
就算Integer i = null,下面还会继续走了,请验证
是的~,,,莫非是NUL ...

Map<String, Integer> map = new HashMap<String, Integer>();
String str = "x";
Integer i = null;
System.out.println(i);

map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));


可以的,不过会报NullPointerException,这就是所问
回复 使用道具 举报
验证了,就算是 map.put("x",null);这样加入,都不会报错
回复 使用道具 举报
黑马唐贤来 发表于 2013-1-20 23:20
我也想了很久这个题,根据判断楼上指出问题出处应该是对的,我想jvm可能会调用Integer.intValue()方法或者是I ...

差不多接近了,再详细指出具体的错误地方
回复 使用道具 举报
柴乔军 发表于 2013-1-20 23:20
i==null? 1 : i
这句话出现的空指针,==判断报出来的i为null;

不对,不过接近了,再仔细看看
回复 使用道具 举报
柴乔军 发表于 2013-1-20 23:21
验证了,就算是 map.put("x",null);这样加入,都不会报错

嗯嗯,再仔细看看,会有发现的
回复 使用道具 举报
基础能力有限啊。。。不看了。。。等楼主公布答案。。
回复 使用道具 举报
柴乔军 发表于 2013-1-20 23:30
基础能力有限啊。。。不看了。。。等楼主公布答案。。

;P
再等其他黑马看看,大家交流一下
回复 使用道具 举报
本帖最后由 黄锦成 于 2013-1-20 23:43 编辑

是这段代码出错了 (map.get(str) + (i==null? 1 : i))
map.get(str)取出的是null,这个(i==null? 1 : i)总会有值的不是1就是5,当进行运算时i会拆箱变成字符串1或5,但是map.get(str)取出的null就变不了,就产生了空指针异常

map.get(str) == null ? i : (map.get(str) + i):乍一看,以为会等map.get(str) == null 这个代码得出结果才去选择左侧的还是右侧,选定之后才回去执行其实都是先会执行结果出来的
        
回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 加入黑马