java String类型与常量池要点

java String类型与常量池要点

1、String是final类,不可被继承;

2、java8 String内部使用char数组存储数据,java9 则是用byte数组存储,同时使用coder变量标识使用那种编码;

3、String内部没有提供修改char[]或byte[]的方法,且它们是final的,且类不可被继承,所以可以确保String不可变;

注:这里的"不可变"是指String对象引用的内存地址里的值不可变;

4、“+”连接符,编译后是使用StringBuilder的append()方法实现的,也就是说1个"+"会隐式创建1个StringBuilder对象并调用append()方法拼接字符串,最后调用toString()返回结果字符串;——所以不要在循环中使用“+”,尤其是循环次数多的情况;

5、“+”连接的若是两个字符串常量,如“123”+“456”则会在编译后就直接得到拼接后的结果,这是编译器对字符串常量的优化;

6、JVM中的字符串常量池内存不会被GC,每当创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已存在则直接返回该字符串在常量池中的地址引用,没有则在常量池创建对象再返回,运行时JVM实例会为字符串常量池维护一个表,表内维护的是常量池中每个对对象的引用;

7、字符串在内存中的地址:

String str1 = "123"; //在常量池;

String str2 = new String("abc"); // 在堆内存,这种情况要注意,若常量池没有“abc”则常量池也会创建一个对象,new String()也会创建一个在堆内存,总共会创建2个对象;

8、判断字符串是否相等:

String s1 = "123";

String s2 = "123";

String s3 = "1234";

String s4 = “12”+“34”;

String s5 = s1+"4";

String s6 = new String("1234");

s1 == s2; // true

s1.equals(s2) // true

s3 == s4 // true,因为s4在编译期就会被优化为s4="1234",所以运行时这两个是指向同一个常量池内存地址;

s3 == s5 // false,s5是 s1连接一个新的字符串"4",首先会在常量池创建"4",然后因为s1是变量,所以运行时会在堆内存隐式创建StringBuilder对象用于拼接字符串,然后用toString()返回结果字符串,这个结果字符串是在堆内存的;

s3.equals(s5) // true

s3 == s6 // false,s6是new的对象,在堆内存;

问题

1、intern()方法,String s = new String( "xxx"),s.intern()时,JVM会先检查常量池是否有“xxx”对象,有则返回它的引用,没有则将“xxx”的引用放入常量池在返回引用,之后再有String s1 =new String( "xxx")时,JVM会先检查常量池,然后直接返回“xxx”的引用,不会再在堆内存的不同位置上再创建一个“xxx”对象;

2、成员变量 static final String s = "xxx" 是否在常量池?答案显而易见,字符串常量肯定是在常量池;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值