概述
(1)运行时常量池属于方法区的一块内存
(2)用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
根据jvm内存区域分布,我们知道
(1)java栈(虚拟机栈)是用于存储局部变量表,操作栈,动态链接,方法出口等信息。(方法执行的时候)
(2)堆:所有对象实例及数组都要在堆上分配内存;
详解
图例:
如图所示,定义a1和a2的时候,在堆中应该创建两个地址,分别用存放两个abc,因此我们用==判断地址是否相等的时候应该返回false;
String a1 = "abc";
String a2 = "abc";
System.out.println(a1==a2);
//true or false ?
运行结果如下:
我们发现运行结果是true,由此可知,abc有另外的一块存储位置;
如下图,我们可以假象,有这样的一块结构在方法区,有一块类似hashset的数据结构,创建一个字符创就会在常量池中创建一个,hashset集合无序不重复,在a1存入的时候,在常量池生成abc,a2进来的时候,现在常量池中查找,是否存在abc,存在的话,直接指向,不存在新建对象;
String a1 = "abc";
String a3 = new String("abc");
System.out.println(a1==a3);
//true or false ?
运行结果如下:
而直接new 创建对象,值一定是在堆内存中,
如上图所示a3和a1并不是一块内存空间,因此返回的是false;
System.out.println(a1 == a3.intern());
//true or false
扩展
intern()方法就是把a3的值取到,丢到常量池里面,产生运行时常量,这样a3.intern()取到的值就是常量池中的值,a1==a3 返回返回true;
直接内存: