JDK源码学习之String类

本文深入剖析了Java中的String、StringBuffer及StringBuilder类的区别与应用场景。详细介绍了String类的内部实现机制,包括其不可变性及内存分配特点,并通过实例对比了String与StringBuilder、StringBuffer在性能上的差异。

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

public final class String implements java.io.Serializable,Comparable<String>,CharSequence{
}
String 类不属于基本数据类型,由于是final类型,所以不能被继承,但是可以序列化
/** The value is used for character storage. */
private final char value[];
使用final类型存储字符串内容,初始化后就不能被修改。
/**Cache the hash code for the String */
private int hash; //Default to 0;
指定缓存字符串的hash code的值,默认为0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
String实现了java.io.Serializble接口,支持序列化接口。
ps:序列化是为了存储整个对象,对象序列化的最主要用处就是在传递和保存对象(Objcet)的时候,保证对象的完整性很可传递性。譬如网络传输、或者把一个对象保存成一个文件的时候,要实现序列化接口。
private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];
ObjectStreamField数组用来申明一个类的序列化字段

String 类中final关键字的使用
final关键字,用来描述一块数据不能被改变,
final使用的三种情况,数据、方法、类,final修饰类、类不能被继承,final修饰方法,方法不能被重载。final修饰基本类型,使得数值不能被改变,但是用于对象引用,虽然能保证初始化后指定一个对象后,就无法指定其他对象,但是对象本身的值确实可以修改;(数组使用final修饰,引用地址不可改变,但是数组的数据却可以改变。);
这个时候 将Class String 使用final修饰,value[] 使用private授予私有访问权限,禁止String 类被继承,房子被子类改写,从而保证String的不可改变,保证其安全性。

了解内存分配和数据存储
数据存储:
1.寄存器:最快的存储区,位于处理器的内部,由于寄存器的数量有限,所以寄存器是按需分配的;ps:如何操作寄存器?寄存器的使用范例?什么时候使用寄存器?
2.栈:位于RAM(随机存储器),但是可以通过栈指针可以从处理器那里获得直接支持,栈指针向下移动,则分配新的内存,栈指针向上移动释放内存。ps:栈中存储基本数据类型和对象引用。但是java 的对象存放在堆中。
3.堆:通用内存池,位于RAM中,用于存放所有的java对象。ps:堆中存储的new创建的对象和数组。
4.常量存储:存放常量。ps:什么是常量。常量:固定不改变的量。一般用final修饰常量。
5.非RAM存储:数据不依赖于程序而存在,如:流对象和持久化对象。

java中基本类型的包装类大部分实现了常量池技术,这些类是Byte、Integer、Long、Character、Boolean,另外两种浮点数类型的包装类则没有实现,另外这5种类型的包装类也只是在对应的小于等于127和大于等于-128时才可使用对象池,不负责创建和管理大于127的这些类对象
String 实现了常量池技术
String 类是java中用的很多的类,同样为了创建String 对象的方便,也实现了常量池的技术。

public class Test{

public static void main(String[] args){

        //s1,s2分别位于堆中不同空间

        String s1=new String("hello");

        String s2=new String("hello");

        System.out.println(s1==s2)//输出false

        //s3,s4位于池中同一空间

        String s3="hello";

        String s4="hello";

        System.out.println(s3==s4);//输出true

    }

}

StringBuffer 和 StringBuilder:java操作可变字符串的类。
StringBuffer源码分析:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;
}
/**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }

    AbstractStringBuilder(int capacity) {
  value = new char[capacity];
}

无参构造方法,构造一个初始容量为16的字符串缓冲区,同时提供多个有参的构造函数,如:

/**
     * Constructs a string buffer initialized to the contents of the
     * specified string. The initial capacity of the string buffer is
     * {@code 16} plus the length of the string argument.
     * @param   str   the initial contents of the buffer.
     */
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

@Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

    // AbstractStringBuilder
    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

append方法前加了同步锁,保证了线程安全,StringBuffer中很多方法都采用同步锁,保证了多线程操作时的同步安全。其中的ensureCapacityInternal方法中对存储空间的分配,如果存储空间不够用的时候,重新new char[] ,存储空间大小为(原始大小+1)*2,最大值为Integer.MAX_VALUE;

StringBuilder跟StringBuffer的操作逻辑一致,只是没有做同步处理。
总结:
String:字符常量
StringBuffer:字符常量(线程安全)
StringBuilder:字符常量(非线程安全)
由此可知:在大部分的情况下,三者在执行速度方面:StringBuilder>StringBuffer>String
用法总结:
String:用于少量需要对字符串进行操作,因为String每次生成对象都会对系统性能产生影响,当内存中无引用对象产生过多时,GC就会开始开始工作。
StringBuilder:单线程下,多次大量的操作字符串,字符串处理时不会产生新的对象,而是对象自身做改变。
StringBuffer:多线程下,多次大量的操作字符串,字符串处理时不会产生新的对象,而是对象自身做改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值