Java字符串和字符串池

String的特性

  1. 不变性
  2. 常量池优化
  3. final关键字修饰

String的不可变

String是不可变的,对于已经存在的String对象的修改都是重新创建一个新的对象然后把值保存进去。

String为什么要设计成不可变的?

  • 便于实现字符串池。
  • 使多线程安全。
  • 避免安全问题。
  • 加快字符串处理速度。

String的常量池优化

JVM为了减少内存开销和提升性能,避免字符的重复创建,其维护了一块特殊的内存空间,即字符串池。
当需要使用字符串时,先去字符串池中查看该字符是否存在,如果存在则直接使用;若不存在,则初始化,并将该字符串放入字符串池中。

堆、栈、方法区和字符串池的位置

  • 堆:堆区被所有线程共享,存储的是被new出来的对象。
  • 栈:栈区中的数据都是私有的,存储的是基本数据类型的对象和自定义对象的引用。
  • 方法区:方法区被所有线程共享,包含所有的在整个程序中永远唯一的元素,如class、static变量。

字符串池位于方法区中,被所有线程共享。

面试题: 两种创建字符串对象的方式

在Java中有两种创建字符串对象的方式:

  • 通过直接赋值创建。
 @Test
    public void testString() {
        String s1 = "123";
        String s2 = "123";
        System.out.println(s1 == s2);
    }
    //true

采用直接赋值的方式创建字符串时,JVM首先会在字符串池中查找是否存在“123”这个对象,如果不存在则在池中创建一个“123”对象,然后将“123”的引用地址返回给字符串常量s1,这样s1会指向池中“123”这个对象。s2在创建时候,字符串池已经存在了“123”这个对象,所以会直接把对象“123”的引用地址返回给s2,故以上代码的最终结果为true。

  • 通过new关键字创建
 @Test
    public void testString() {
        String s1 = new String("123");
        String s2 = "123";
        System.out.println(s1 == s2);
    }
    //false

采用new创建一个字符串对象s1时,JVM首先会在字符串池中查找是否存在“123”这个对象,如果不存在则在池中创建一个“123”对象,如果存在则直接在堆中创建一个“123”字符串对象,然后将堆中的这个“123”对象的地址返回赋给s1。但是由于在使用new对象创建字符串对象时,每次new出来的都是一个新的对象,因此此代码执行结果为false。

面试题:String创建对象的数量

下列有几种情况,均不考虑字符串池已有的情况,下列代码创建了多少个对象?

一:

String str = "ABC";

仅在池中创建了一个"ABC"对象。

二:

String str = new String("ABC");

创建了两个对象:

  • 第一个对象:在池中创建"ABC"。
  • 第二个对象:通过new关键字在堆中创建的new String()对象。

三:

String str = new String("A" + "B");

创建了四个对象

  • 第一个对象:在池中创建"A"。
  • 第二个对象:在池中创建"B"。
  • 第三个对象:在池中创建"AB"。
  • 第四个对象:通过new关键字在堆中创建的new String()对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值