常量池:
常量池在java用于保存在编译器已经确定的,以编译的class文件中的一份数据,包括关于类, 方法,接口也包括j字符串常量。
java是一种动态链接的语言,常量池除了包含代码所定义的各种基本类型外(int ,long)和对象型(String ,数组)的常量外,还包含一些文本形式出现的符号引用。
在c语言中,如果一个程序调用其他库函数,在连接时,该函数在库中的位置,会被写在程序中,在运行的时候。会直接去这个地址调用该函数。
而在java中,一切都是动态的,编译时,如果发现其其它类方法的调用者或对其它类字段的引用的语句,记录进class文件中的只能是一个文本形式的符号引用,在连接过程中,虚拟机会根据这个文本信息去查找对应的方法或字段。
拘留字符串对象:
源代码中所有相同字面值的字符串常量只可能建立一个唯一的字符串对象,在java程序中可以调用String的intern ()方法来使得一个常规的字符串对象称为拘留字符串对象。
(1)String s = new String (“hello ,world”); JVM在执行这段指令之前,JVM就已经为“hello,World”在堆中创建一个拘留字符串(注意:如果源程序中还有一个“hello,world”字符串常量,那么字符他们都对应同一个堆中的拘留串)然后用这个拘留字符串的值来初始化堆中用new指令创建的新的String对象, 局部变量存储的是new出来的堆对象地址
完成上面(1)然后执行 String s = “hello,world”;
此时局部变量s存储的早已是创建好的拘留字符串的堆地址
java常量池技术:
java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中获取一个出来(如果池中没有创建一个)则在需要重复创建相等变量是时节省了很多时间,常量池就是一个内存空间,常量池存在于方法区中。
java中基本类型的包装类大部分都实现了常量池技术,如Byte,Short,Integer,Long ,Character,Boolean另外两种包装类则没有实现常量池,Byte,Short,Integer,Long ,Character 这五种包装类型也只是在对应的值小于等于127时才可以使用对象池。如果超过127则不会创建和管理这些对象
示例代码如下:
// 堆中空间
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
System.out.println(i1==i2);// false
// 常量池空间
Integer i3 = 1;
Integer i4 = 1;
System.out.println(i3==i4);// true
System.out.println(i1==i3);// false (i1 与i3 位不同的内存空间)
System.out.println("------------------------------------>");
Integer a = 128;
Integer b = 128;
Integer c = new Integer(128);
System.out.println(a==b);//false (值大于127时不会从常量池取对象)