JDK源码分析之String(一)

本文探讨了Java中String类的不可变性,分析了其内部的final修饰和char数组存储方式,通过测试代码展示了String在赋值操作时如何返回新实例。此外,还介绍了两种常见的String声明方式及其在内存中的表现,为理解JVM对String的优化打下基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要

日常使用java中,java.lang.String类几乎是使用最为频繁的一个类,此系列主要介绍String的具体实现以及作者对其进行了什么样的优化操作。

实现

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
private int hash;
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];
//其他函数
......
}

String的一些基本信息

1.String被final修饰符修饰,表示String是一个不可变类,一旦创建,就无法修改其中的内容。
2.实现了java.io.Serializable, Comparable<String>, CharSequence三个接口
3.String中储存核心内容的数据结构是一个char数组。

String的不可变特性

前面说到String由final修饰,并且所有可能更改其核心存储内容的char[]数组的方法的返回值全都是返回一个新的字符串,保证了char[]无法被修改。
测试代码

public static void main(String[] args) {
        String v="This is a String value!";
        char[] c=new char[]{'a','s','d'};
        change(v,c);
        System.out.println(v);
        System.out.println(c);
    }
    private static void change(String value,char c[]){
        value="This is a New String value!";
        c[0]='N';
    }

为了对比,我们引入char数组
如果你认为输出是:

This is a String value!
Nsd

那你就忽略了String类的不可变特性。
首先,我们初始化了一个String和char[]变量,其指向的值分别为This is a String value!a``s``d,调用change(String value,char c[])方法时,将双方的地址传入方法。
最初,方法参数value指向传入的参数v,此时传入的参数v的地址指向This is a String value!的地址,所以value指向的值为This is a String value!。当重新向方法参数value赋值时,由于String的不可变性,方法参数value指向了新地址This is a New String value!。char[]则直接改变了存在内存中的内容。函数调用完毕,继续执行下一步。
由于要输出v的值,此时v依然指向This is a String value!的地址,c指向的也同样是一开始数组的地址,而方法体直接改变了地址中的值。
所以输出应该为

This is a String value!
Nsd

栈区指向的地址不变
上图中可以了解到,栈区指向的地址不变,而只有char[]数组在内存中实际发生了改变。

String的声明方式

常用的两种方式

String s1="This is a String value!";
String s2=new String("This is a String value!");

那么这两种声明方式对java来说有什么不一样的地方呢?
测试代码

String value1="This is a String value!";
String value2="This is a String value!";
String value3=new String("This is a String value!");
System.out.println(value1==value2);
System.out.println(value1==value3);
System.out.println(value2==value3);

输出

true
false
false

上一节说到==操作符比较的是两者引用的地址是否一致。
也就是说value1``value2指向的是同一个地址
内存中的情况
这是JVM对String的第一处优化。
具体细节,下节再讲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值