关于封装类如Integer的问题

kangkings98 2009-10-22 08:29:53
Integer i=10;
如此用Integer构造了已经对象i,并赋值10.那么这个i就是对一个Integer对象的引用,如果我们这样i=20,改变了i的值,那么其实我们是重新构造了一个Integer对象,并赋值20,然后用i引用,原来的那个值为10的对象,其实还是存在的,只是缺少引用。我这样说对吗?
...全文
211 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
wifewifewife 2009-10-23
  • 打赏
  • 举报
回复
其实在18楼的时候你自己不是把这段代码贴出来了吗?
private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
其实还应该把这段代码加进去就明白了:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) {
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
所有的奥秘都在这里面了。下面我帮你解释一下这段代码吧。不过我不敢保证解释得完全对,让大家来拍砖吧。
楼主说得对,java现在是通过jvm来自动装箱的。但jvm实际上是自动调用的valueOf()这个方法。很明显,Integer e= 10其实就是Integer.valueOf(10),也就是说在-128到127都被静态化了,静态化的变量地址是不变的。所以Integer e = 10与Integer f = 10;System.out.println(e==f);这个肯定为true的。
但是当你Integer g = 128时,也就是说不在-128到127这个静态化范围之外时,他会怎样呢?请看代码:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) {
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
它实际上是return new Integer(i),它new了一个对象,我们知道Integer是引用类型,在里面重新new了一次,等于又会重新返回一个引用,所以地址也被改变了。
举个简单的例子:
Integer h=128;Integer i=128;system.out.println(h==i);这个会为true吗?肯定不对,因为它们在里面重新new了一次,等于又会重新返回一个引用,所以地址被改变了。也就是说这是两个不同的引用,两个不同的地址。表达能力不行,不知道这样大家明不明白。
hjhgg 2009-10-22
  • 打赏
  • 举报
回复
偶帮顶起来啊
lz12366007 2009-10-22
  • 打赏
  • 举报
回复
我怎么觉得大家讨论的不是lz说的问题呢
dsgdsg 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 kangkings98 的回复:]
把楼上的代码稍微改了下,发现一个有趣的东西
public static void main(String[] args) {
Integer i=128; //大于等于128
        Integer j=i;
        System.out.println(i==j);
        System.out.println(i+"--"+j);
        j=20;
        j=128; //大于等于128和上面对应的i相等再看看
        System.out.println(i==j);
        System.out.println(i+"--"+j);

}
输出
true
10--10
true
10--10

也就是说,但我将j赋值一定新的值为20的对象后,在又赋值一个10的对象,其实系统并没有真正的再建一个值为10的对象,而只是重新将j的引用指向i引用的那个对象。

[/Quote]

Integer在-128 到127的范围使用的是简单int型,,超过了才才是创建的对象!
wifewifewife 2009-10-22
  • 打赏
  • 举报
回复
string是final类型;integer是引用类型,如果像Integer integer1 = 10,这样的话,它是放在常量池中,属于栈内存中吧,因为是在常量池中,所以里面只有一个integer1,无法你怎么改变这个值,最后一次的赋值就是integer1的值;如果是Integer integer2 = new Integer(10)的话,这是创建了一个对象了,integer2不会放入常量池中,他将会放入堆内存中,所以只要你new了一个对象出来的话,地址就永远不会相等。
ajwyyan 2009-10-22
  • 打赏
  • 举报
回复
应该没有新建对象,只是把对象i的值地址对应该的值改变了
kangkings98 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 ima 的回复:]
看看Integer的源码就知道,在-128到127之间的int值都是放在IntegerCache的缓存中,所以不会新创建对象,你对j赋值一个1111111试试
[/Quote]

private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
大侠,你是指这段吗,老实说,功力不够,看不懂。
李子做IT 2009-10-22
  • 打赏
  • 举报
回复
原理和string的内存池一样,这个一直在内存池中,并没有新建对象,地址还是一样的。
不管多少个10,他们都指向同一个内存池中的地址。
imA 2009-10-22
  • 打赏
  • 举报
回复
看看Integer的源码就知道,在-128到127之间的int值都是放在IntegerCache的缓存中,所以不会新创建对象,你对j赋值一个1111111试试
阿_布 2009-10-22
  • 打赏
  • 举报
回复

public static void main(String[] args) {
Integer i=150;
Integer j=i;
System.out.println(i==j);
System.out.println(i+"--"+j);
j=150;
//j=10;
System.out.println(i==j);
System.out.println(i+"--"+j);

}

lz这样试一下就知道了,创建了一个对象的,后面加j=10的话,因为前面创建了值为10的Integer对象,对象池中已经有了,就会去对象池中的引用。在-128-127范围外就不会从对象池中取。
fsn011362 2009-10-22
  • 打赏
  • 举报
回复
其它基本类型是否也都有这样的机制呢?
smallbear923 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 kangkings98 的回复:]
也就是说,如果两个Integer,如果他们的值相同的话,他们其实是同一个对象,这么说对吗?
[/Quote]
是的。
kangkings98 2009-10-22
  • 打赏
  • 举报
回复
也就是说,如果两个Integer,如果他们的值相同的话,他们其实是同一个对象,这么说对吗?
Solidsnake1987 2009-10-22
  • 打赏
  • 举报
回复
int 只是单纯的内存地址引用.. 你的内存地址可变吗?
kangkings98 2009-10-22
  • 打赏
  • 举报
回复
把楼上的代码稍微改了下,发现一个有趣的东西
public static void main(String[] args) {
Integer i=10;
Integer j=i;
System.out.println(i==j);
System.out.println(i+"--"+j);
j=20;
j=10;
System.out.println(i==j);
System.out.println(i+"--"+j);

}
输出
true
10--10
true
10--10

也就是说,但我将j赋值一定新的值为20的对象后,在又赋值一个10的对象,其实系统并没有真正的再建一个值为10的对象,而只是重新将j的引用指向i引用的那个对象。
shoulders 2009-10-22
  • 打赏
  • 举报
回复
自己写程序看一下,两次的I的对象是不一样的。
阿_布 2009-10-22
  • 打赏
  • 举报
回复
Integer类在-128-127范围内和String是一样的,超过这个范围就不是了。
捏造的信仰 2009-10-22
  • 打赏
  • 举报
回复
是的。
gukuitian 2009-10-22
  • 打赏
  • 举报
回复

public static void main(String[] args)
{
Integer i=10;
Integer j=i;
System.out.println(i==j);
System.out.println(i+"--"+j);
j=20;
System.out.println(i==j);
System.out.println(i+"--"+j);
}
试试就知道了。
孤尽JavaSea 2009-10-22
  • 打赏
  • 举报
回复
这是引用的道理,非常明确的。
引用被改变,原先被引用的那块就置成null,等着gc()来拖了。
加载更多回复(6)

62,616

社区成员

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

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