String深入理解

1 String对象存放位置

1) 直接指定内容的String对象存放在字符串常量池中

String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2);  // true

s2直接指向s1的内存地址,两者共用同一个字符串,都在常量池中

2) 只有使用引号包含文本方式创建的String对象之间使用"+"链接产生的新对象才会被加入到字符串池中,其他的要在堆中创建
即只有常量用"+"连接才放入字符串池中

String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8;
System.out.println(s1 == s9);  // false

s7,s8在字符串常量池中创建,s9在堆中创建
在这里插入图片描述

3)在 Java中,使用 new创建的对象,都存放在堆中

String s4 = "Hel" + new String("lo");

在这里插入图片描述

2 特例
  • 特例1
public static final String A = "ab"; // 常量A
public static final String B = "cd"; // 常量B
public static void main(String[] args) {
     String s = A + B;  // 将两个常量用+连接对s进行初始化 
     String t = "abcd";   
    if (s == t) {   
         System.out.println("s等于t,它们是同一个对象");   
     } else {   
         System.out.println("s不等于t,它们不是同一个对象");   
     }   
 } 
s等于t,它们是同一个对象

A和B都是常量,值是固定的,因此s的值也是固定的,它在类被编译时就已经确定了。也就是说:String s=A+B; 等同于:String s=“ab”+“cd”;

  • 特例2
public static final String A; // 常量A
public static final String B;    // 常量B
static {   
     A = "ab";   
     B = "cd";   
 }   
 public static void main(String[] args) {   
    // 将两个常量用+连接对s进行初始化   
     String s = A + B;   
     String t = "abcd";   
    if (s == t) {   
         System.out.println("s等于t,它们是同一个对象");   
     } else {   
         System.out.println("s不等于t,它们不是同一个对象");   
     }   
 } 
s不等于t,它们不是同一个对象

A和B虽然被定义为常量,但是它们都没有马上被赋值。在运算出s的值之前,他们何时被赋值,以及被赋予什么样的值,都是个变数。因此A和B在被赋值之前,性质类似于一个变量。那么s就不能在编译期被确定,而只能在运行时被创建了

3 总结
  • 必须要关注编译期的行为,才能更好的理解常量池
  • 运行时常量池中的常量,基本来源于各个class文件中的常量池
  • 程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值