String类还有这么多奇技淫巧

每日Java基础篇(一)--String类

String是只读字符串,它并不是基本数据类型,而是一个引用类型的对象。从底层源码来看是一个final修饰的类,表明类不能被继承,属性value是String类储存数据的char字符数组(JDK8),(JDK11改成了byte字节数组),同时被final修饰,即所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的String对象。 源码可以看出。
在这里插入图片描述

问题一

引用数据类型使用==判断的是对象引用是否是同一个引用,判断字符串相等要用equals方法

    public static void main(String[] args) {
        String a = "taobao";
        String b = "tao"+"bao";
        String c = new String("taobao");
        System.out.println(a == b); // true
        System.out.println(a == c); // false
        System.out.println(b == c); // false
}

String a = “taobao”,String a = “tao”+“bao”,String a = new String(“taobao”)之间的区别?

String a = "taobao";执行过程是:
到方法区的常量池中寻找"taobao",
1、如果存在,则直接将"taobao"对象的地址传递给a;
2、如果不存在,则在常量池中创建"taobao",然后将地址传递给a.

String b = "tao"+"bao";这句话执行过程是:
1、在hotspot虚拟机中 编译"tao"+"bao"将直接优化成"taobao"
2、然后和String a = "taobao";执行过程一样,所以未true

String a = new String("taobao");执行过程是:
首先在堆内存中创建对象"taobao",然后在常量池中寻找"taobao",
1、如果存在,把堆内存地址传递给a;
2、如果不存在,在常量池中创建"taobao"对象,然后把堆内存地址传递给a;

总结: 直接赋值形式的新建string对象是从常量池中拿数据;最多创建一个string对象,虽少创建0个string对象;new形式新建string对象无论怎样会首先在堆内存中创建一个string对象,然后确保常量池中也有一个相同内容的string对象;最多创建2个,最少创建1个。

由于直接赋值方式可能节约内存,推荐使用该方式。

问题二

重新赋值st字符串变量,是否发送改变?

 public static void main(String[] args) {
     String st = "hello";
     st = "world";
     System.out.println(st); // world
 }

在这里插入图片描述

问题三

public class Question_6 {
    private static final String Message = "taobao";

    public static void main(String[] args) {
        String a = "tao"+"bao";
        String b = "tao";
        String c = "bao";
        System.out.println(a == Message); // true
        System.out.println((b+c) == Message); // false
    }
}

b+c不会优化,因为不知道在之前的步骤中bc会不会发生改变,而针对b+c则是用语法糖,新建一个StringBuilder来处理,所以在堆中产生对象,故和Message的地址不相等
在这里插入图片描述

问题四

public class Question_6 {
    private static final String Message = "taobao";

    public static void main(String[] args) {
        String a = "tao"+"bao";
        final String b = "tao";
        final String c = "bao";
        System.out.println(a == Message);  // true
        System.out.println((b+c) == Message); // true
    }
}

final关键字修饰的局部字符串变量相连接时,Hotspot虚拟机在编译时会优化成"taobao",因为被final修饰的变量是不可变的常量。如果在字符串相加中,只要有一个是非final类型的变量,编译器就不会优化,因为这样的变量可能发生改变,所以编译器不可能将这样的变量替换成常量。例如将变量b的final去掉,结果(b+c) == Message变成了false。这也就意味着会用到StringBuilder对象,在堆内存中产生新对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李熠漾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值