[快乐开发] 谁能告诉我java中的常量池和堆之间是否有交集 两者的关系是怎样的?

liumik 2010-11-30
<>++< 写道
举例说明吧:
String str1 = "China";
String str2 = "China";
System.out.println(str1 == str2);//true
因为两个String的引用地址是一样的 所以比引用返回true 这个没问题
但:
Integer n3 = 128;
Integer n4 = 128;
System.out.println(n3 == n4);//false
因为两个Integer的引用地址也都是常量池中128的内存地址 为什么比引用就返回false?
(因为-128~127是存在cache中的 所以用这区间的整数举例会返回true)
---------------------------------这是为啥啊 阿九??

字符串常量在Java中是对象;整数常量在Java中不是对象。
因此字符串常量复制给字符串对象,只是简单的引用赋值;
整数赋值给整数对象,是根据整数值new的一个对象,然后赋值(好像叫自动box?)
lijingyao8206 2010-11-30
何必有交集,不必有交集……常量池就是单独出来给字符串这个麻烦东东用的,也是JVM很好的设计理念,有了它我们就会节省很多创建对象在堆里的空间。复用常量池中的东东可以提高空间利用率,而且让堆里的对象不至于太泛滥哈。
<>++< 2010-11-30
lijingyao8206 写道
何必有交集,不必有交集……常量池就是单独出来给字符串这个麻烦东东用的,也是JVM很好的设计理念,有了它我们就会节省很多创建对象在堆里的空间。复用常量池中的东东可以提高空间利用率,而且让堆里的对象不至于太泛滥哈。

是有交集的 think in java 上写的 只不过那本书没说两者的关系 你说的这些我都知道 不过谢谢回复
<>++< 2010-11-30
liumik 写道
<>++< 写道
举例说明吧:
String str1 = "China";
String str2 = "China";
System.out.println(str1 == str2);//true
因为两个String的引用地址是一样的 所以比引用返回true 这个没问题
但:
Integer n3 = 128;
Integer n4 = 128;
System.out.println(n3 == n4);//false
因为两个Integer的引用地址也都是常量池中128的内存地址 为什么比引用就返回false?
(因为-128~127是存在cache中的 所以用这区间的整数举例会返回true)
---------------------------------这是为啥啊 阿九??

字符串常量在Java中是对象;整数常量在Java中不是对象。
因此字符串常量复制给字符串对象,只是简单的引用赋值;
整数赋值给整数对象,是根据整数值new的一个对象,然后赋值(好像叫自动box?)

你是在解释引用类型和基本类型的区别么?
第一句不是很认同 字符串常量和整数常量在java中均是对象 只不过一个是引用类型的对象 一个是值类型的对象。
<>++< 2010-11-30
chenhua_xy 写道
Integer n3 n4 ->int包装类当然是对象必然存放在堆空间,只要是对象都在堆空间
字符串常量才是放在方法区的常量池的 常量池放置的是直接常量(String,integer,float point常量)和对其他字段,方法,类型的符号引用。

恩 没错 不过想请教下“和对其他字段,方法,类型的符号引用。”这句话。 能举个例子么? 因为不理解引用为什么还会放到常量池中?
<>++< 2010-11-30
trydofor 写道
>(因为-128~127是存在cache中的 所以用这区间的整数举例会返回true)
这是个圈套,看你是用==还是equals,是new还是box

// jdk1.4 & 6
Integer n3 = new Integer(1);
Integer n4 = new Integer(1);
System.out.println(n3 == n4);//false

// jdk6
Integer n3 = 12;
Integer n4 = 12;
System.out.println(n3 == n4);//true


对 没错 刚才看了下资料 后半段代码:
// jdk6
Integer n3 = 12;
Integer n4 = 12;
jvm根本没对12这个常量进行box 所以用==比较的时候其实是比较的值 因为当该常量小于1字节(-128~127 =255)时 比较值和比较地址所耗费的资源成本是一样的 所以比较值, 当该常量大于1字节大小时 就超出了jvm中默认设定的cache范围,自然耗费的成本就不同了 所以jvm会将128进行box 然后比较n3 n4就是比较引用了。
suntao19830709 2010-11-30
Crusader 昨天的回复是对的。。。为啥就没人看呢?
<>++< 2010-12-02
suntao19830709 写道
Crusader 昨天的回复是对的。。。为啥就没人看呢?

没人说Crusader错了啊  说的请简洁明确!
darell 2010-12-07
java常量池跟类信息一样存在于perm size(即永生代)里面的内存。
lazybird86 2010-12-08
引用
A runtime constant pool is a per-class or per-interface runtime representation of the constant_pool table in a class file (§4.4). It contains several kinds of constants, ranging from numeric literals known at compile time to method and field references that must be resolved at run time. The runtime constant pool serves a function similar to that of a symbol table for a conventional programming language, although it contains a wider range of data than a typical symbol table.
Each runtime constant pool is allocated from the Java virtual machine's method area (§3.5.4). The runtime constant pool for a class or interface is constructed when the class or interface is created (§5.3) by the Java virtual machine.

在jvm规范里,运行时常量池是在方法区内分配的。
对类解析时需要用到常量池。
至于它们的关系,事实上没有直接关系。拿我们常见的字符串常量,其实在解析字符串常量池时,jvm会“拘留”字符串常量(有列表记录着拘留的字符串引用),这时会在堆创建一个字符串对象,String也提供intern方法用于显示“拘留”。
我的理解如上,不知道有没有大鸟指正?
Global site tag (gtag.js) - Google Analytics