常量池

常量池

Java中的常量池分为两种,一种是静态常量池,一种是运行时常量池。

静态常量池

是class文件中的常量池,包含字符串(数字)字面量,类,方法的信息。占用class文件的绝大部分空间。

这种常量池主要存放两大类常量:字面量和符号引用量。

字面量:

字面量可以理解为实际值,也可以理解为描述了自己的量。比如int a=3;3就是字面量。再比如String s=”abc“;abc就是字面量

符号引用量:

包括类和接口的全限定名。

字段名称和描述符。

方法名称和描述符

限定类名:就是类名全称,带包路径的用点隔开,例如java.lang.String

非限定类名:就是平时所说的类名,不带包的。如String。

运行时常量池

​ 指的是jvm虚拟机完成类的加载工作时,将class文件中的常量池载入到内存的方法区中,并保存下来。我们经常说的常量池,指的就是这个。

​ 运行时常量池具有*动态性,*意思是指,java中的常量并不一定必须在编译时才能产生。在程序执行的过程中也可能将常量放入常量池中。

另注:其实运行时字符串常量池中的常量,基本来源于各个class文件中的常量池。程序运行时,除非手动向常量池中添加常量(比如使用intern方法),否则jvm不会自动添加常量到常量池。

常量池的优点

1.常量池的存在可以避免频繁的创建和销毁对象,从而影响程序性能。

2.节省内存空间。以字符串常量池为例:常量池中所有的相同的字符串常量通常会被合并。只占用一个空间。

3.节省运行时间。比较字符串时比equals快。对于两个引用型变量。只用判断引用是否相等。就可以判断值是否相等。

另注:java中直接使用==比较的是两个字符串的引用地址。并不是比较内容。比较内容可以使用String.equals()

常量池的一些例子

public class Test {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        String s3 = "hel" + "lo";
        String s4 = "hel" + new String("lo");
        String s5 = new String("hello");
        String s6 = s5.intern();
        String s7 = "h";
        String s8 = "ello";
        String s9 = s7 + s8;

        System.out.println(s1==s2);//ture
        System.out.println(s1==s3);//ture
        System.out.println(s1==s4);//false
        System.out.println(s1==s9);//false
        System.out.println(s4==s5);//false
        System.out.println(s1==s6);//ture
    }
}

分析:

s1==s2,s1和s2在编译时作为字面量进入静态常量池。随后被加载进方法区中的动态常量池中,此时,二者指向的是同一个地址值。所以为ture

s1==s3,s3为已知的字符串常量拼接而成。在编译时会自动优化成”hello“存储在class文件中。即为string s3=“hello”所以为ture

另注:只有使用引号包含文本的方式创建的String对象之间使用+连接产生的新对象才会被加载进字符串常量池中。

s1==s4,s4虽然也是拼接,但是包含new方式创建对象。编译时new String(“lo”)是变量,是不可知的。编译器不会优化。所以不会加载进运行时常量池,而是在堆内存中分配空间。地址当然不同。结果为false

(s1==s9),同理,s7,s8编译时是变量,不可知,所以不会加载进运行时常量池。在堆内存中分配空间。地址不同,结果为false。

(s4==s5),虽然都在堆内存中,但是地址值 不相同。结果为false

(s1==s6),intern()方法的作用是:查找常量池中是否有equals相等的字符串。如果有则返回字符串的引用。如果没有就添加自己的字符串进常量池。常量池中有“hello”所以返回常量池中的地址值。与s1地址值相同。结果为ture

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值