Java中Integer问题,final value怎么回事?

houliang120 2015-05-27 07:58:52
刚开始学习java,晚上遇到一个棘手的问题!直接看代码吧
下面是一段从jdk1.7中拷贝的Integer的代码段
private final int value;
public Integer(int value) {
this.value = value;
}
这里的意思就是value是常量,然后下面是一个构造器,然后我的测试如下:
Integer in = 1000;//问题1
Integer in1 = in; //问题2
System.out.println( "first:"+in.intValue() + " "+in1.intValue());
in1 = 1020;//问题3
System.out.println( "second:"+in.intValue() + " " + in1.intValue() );
问题列出如下:
问题1:简单的浏览了一下Integer.java,结合书上的介绍,当赋值在-128-127之间时,用缓存值(在方法valueof里面),那么这行代码的调用顺序是什么?不是直接调用构造器?
问题2:同样这里的调用顺序有是什么?
问题3:这个比较费解,上述value明明就是final,这里怎么就变了呢?难道是赋值改变导致创建了一个新的对象?
...全文
567 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
houliang120 2015-05-30
  • 打赏
  • 举报
回复
引用 5 楼 whos2002110 的回复:
[quote=引用 3 楼 houliang120 的回复:] [quote=引用 1 楼 u014232653 的回复:] 当赋值在-128-127之间时,用缓存值,这是没错的 Integer in = 1000;//问题1 这个就是相当于Integer in =new Integer(1000); 而Integer in1 = in; //问题2 相当于in1这个变量指向了与in相同的地址,故其值与in相同均为1000 而in1 = 1020;//问题3 就和问题1一样,in1又重新new出了一个对象,即in1 =new Integer(1020);这时in1这个变量指向的地址就改变了,而in这个变量指向的地址不变 至于你说的那个,value明明就是final,这里怎么就变了呢?你说的没错,赋值就相当于创建了一个新的对象,但是如果你附的值是在-128-127之间的,就会直接用缓存中的值而不是新new对象。
您说的很清楚,运行的结果我也明白了,但是还有疑问,假如我这样用: Integer i = 1000; //调用构造器,将域value置为1000 i1 = 100; 问题如下:第二句i1=100,这里是不是调用valueOf这个函数,然后使用缓存值,就不会new一个新对象? 如果是这样的话,我看了一下代码: public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 代码没有修改value的值,既然没有创建新对象,i1还是指向原来的对象,value应该是原来的1000,但是通过Field获取value得出的是100,这是怎么回事? 我刚学java,还请耐心回复,描述有错,还望指出来!谢谢 [/quote] 你的理解基本都是正确的,当我们使用 Integer i = xxx; 这样的语句时,是在使用自动装箱功能,自动装箱就是调用了valueOf()方法, 显然如果大于127 会new 新的。如果cache范围内就返回IntegerCache.cache[i + (-IntegerCache.low)]; 这句的结果,你再把它里面的代码看一下就明白了全部的过程。 虽然你没有创建对象,但 i1 已经指向cache里面的100了,当然不再是原来的1000。[/quote] 谢谢您的解答,说的很精准!之前没有仔细看IntegerCache里面的代码,刚才分析了一下,搞明白了,谢谢了!
whos2002110 2015-05-29
  • 打赏
  • 举报
回复
引用 3 楼 houliang120 的回复:
[quote=引用 1 楼 u014232653 的回复:] 当赋值在-128-127之间时,用缓存值,这是没错的 Integer in = 1000;//问题1 这个就是相当于Integer in =new Integer(1000); 而Integer in1 = in; //问题2 相当于in1这个变量指向了与in相同的地址,故其值与in相同均为1000 而in1 = 1020;//问题3 就和问题1一样,in1又重新new出了一个对象,即in1 =new Integer(1020);这时in1这个变量指向的地址就改变了,而in这个变量指向的地址不变 至于你说的那个,value明明就是final,这里怎么就变了呢?你说的没错,赋值就相当于创建了一个新的对象,但是如果你附的值是在-128-127之间的,就会直接用缓存中的值而不是新new对象。
您说的很清楚,运行的结果我也明白了,但是还有疑问,假如我这样用: Integer i = 1000; //调用构造器,将域value置为1000 i1 = 100; 问题如下:第二句i1=100,这里是不是调用valueOf这个函数,然后使用缓存值,就不会new一个新对象? 如果是这样的话,我看了一下代码: public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 代码没有修改value的值,既然没有创建新对象,i1还是指向原来的对象,value应该是原来的1000,但是通过Field获取value得出的是100,这是怎么回事? 我刚学java,还请耐心回复,描述有错,还望指出来!谢谢 [/quote] 你的理解基本都是正确的,当我们使用 Integer i = xxx; 这样的语句时,是在使用自动装箱功能,自动装箱就是调用了valueOf()方法, 显然如果大于127 会new 新的。如果cache范围内就返回IntegerCache.cache[i + (-IntegerCache.low)]; 这句的结果,你再把它里面的代码看一下就明白了全部的过程。 虽然你没有创建对象,但 i1 已经指向cache里面的100了,当然不再是原来的1000。
houliang120 2015-05-29
  • 打赏
  • 举报
回复
引用 2 楼 alan19931103 的回复:
1,调用构造器 2,就只是引用指了一下 3,对象没变,引用指了一个新对象,引用不是final的可以变。
您说的比较简洁,结合书也能看明白,但是还有疑问,假如我这样用: Integer i = 1000; //调用构造器,将域value置为1000 i1 = 100; 问题如下:第二句i1=100,这里是不是调用valueOf这个函数,然后使用缓存值,就不会new一个新对象? 如果是这样的话,我看了一下代码: public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 代码没有修改value的值,既然没有创建新对象,i1还是指向原来的对象,value应该是原来的1000,但是通过Field获取value得出的是100,这是怎么回事? 我刚学java,还请耐心回复,描述有错,还望指出来!谢谢
houliang120 2015-05-29
  • 打赏
  • 举报
回复
引用 1 楼 u014232653 的回复:
当赋值在-128-127之间时,用缓存值,这是没错的 Integer in = 1000;//问题1 这个就是相当于Integer in =new Integer(1000); 而Integer in1 = in; //问题2 相当于in1这个变量指向了与in相同的地址,故其值与in相同均为1000 而in1 = 1020;//问题3 就和问题1一样,in1又重新new出了一个对象,即in1 =new Integer(1020);这时in1这个变量指向的地址就改变了,而in这个变量指向的地址不变 至于你说的那个,value明明就是final,这里怎么就变了呢?你说的没错,赋值就相当于创建了一个新的对象,但是如果你附的值是在-128-127之间的,就会直接用缓存中的值而不是新new对象。
您说的很清楚,运行的结果我也明白了,但是还有疑问,假如我这样用: Integer i = 1000; //调用构造器,将域value置为1000 i1 = 100; 问题如下:第二句i1=100,这里是不是调用valueOf这个函数,然后使用缓存值,就不会new一个新对象? 如果是这样的话,我看了一下代码: public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 代码没有修改value的值,既然没有创建新对象,i1还是指向原来的对象,value应该是原来的1000,但是通过Field获取value得出的是100,这是怎么回事? 我刚学java,还请耐心回复,描述有错,还望指出来!谢谢
alan19931103 2015-05-28
  • 打赏
  • 举报
回复
1,调用构造器
2,就只是引用指了一下
3,对象没变,引用指了一个新对象,引用不是final的可以变。
xia夜 2015-05-27
  • 打赏
  • 举报
回复
当赋值在-128-127之间时,用缓存值,这是没错的 Integer in = 1000;//问题1 这个就是相当于Integer in =new Integer(1000); 而Integer in1 = in; //问题2 相当于in1这个变量指向了与in相同的地址,故其值与in相同均为1000 而in1 = 1020;//问题3 就和问题1一样,in1又重新new出了一个对象,即in1 =new Integer(1020);这时in1这个变量指向的地址就改变了,而in这个变量指向的地址不变 至于你说的那个,value明明就是final,这里怎么就变了呢?你说的没错,赋值就相当于创建了一个新的对象,但是如果你附的值是在-128-127之间的,就会直接用缓存中的值而不是新new对象。

62,615

社区成员

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

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