关于java常量池的一点思考

首先我们来看下面一个题

如下代码运行结果是什么?

Character c1=134;
Character c2=134;
Character c3=13;
Character c4=13;
System.out.println("c1==c2"+(c1==c2));
System.out.println("c3==c4"+(c3==c4));

程序运行的结果为:

c1==c2false
c3==c4true

为什么会得到这个结果呢?我们得从常量池说起。

1.什么是常量池?

 Java内存大题可以分为堆、栈、常量池、方法区。它们的基本区别如下图:

stack

存取速度快

数据可以共享

数据大小和生命周期必须确定,不够灵活

 

heap

运行时数据区

运行时动态分配内存

自动回收垃圾

存取速度较慢

方法区

method area

用来存储类型信息

 

 

常量池 

constant pool

用来存储某类型的常量信息

 

 

由此可见,常量池是方法区的一部分,是内存的逻辑分区。使用如果两个变量使用常量池中的数据,那么两个变量指向常量池中相同的地址,否则他们都会新创建一个对象,指向不同的地址。看以下代码

Integer i1=10;
Integer i2=10;
Integer io1=new Integer(10);
Integer io2=new Integer(10);
System.out.println("i1==i2"+(i1==i2));
System.out.println("io1==io2"+(io1==io2));

i1、i2使用到了自动装箱,io1和io2则没有使用;i1 i2使用到常量池,io1、io2没有使用。因此程序的运行结果如下:

i1==i2true
io1==io2false

i1和i2的值都是10,所以指向常量池中相同的空间;因此i1==i2返回true;io1和io2使用new创建赋值,所以分别指向堆中不同的空间,因此io1==io2返回false;如下图:

注意:在自动装箱拆箱过程中,只有数值是byte范围内的时候,才使用到常量池,否则都是分配新的内存空间;

如以下代码:

Integer i3=1000;
Integer i4=1000;
Integer io3=new Integer(1000);
Integer io4=new Integer(1000);
System.out.println("i3==i4"+(i3==i4));
System.out.println("io3==io4"+(io3==io4));

1000早就超出了byte的范围,所以i3/i4是两个空间;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值