字符串(String, StringBuilder, StringBuffer)

String

Java提供了String类型来表示字符串

保存字符串的方式

String类中用来保存字符串的数据接口是一个byte[],并且用fianl修饰了这个数组。

private final byte[] value;

String类没有提供接口来修改字符串的值,所以String是不可以被修改的,而且是线程安全的。

创建字符串

创建字符串有两种方式:

  1. String str = “abc”。当使用这种方式创建字符串时,JVM会在堆内存中搜索看之前是否有用这种方式创建过"abc"字符串,如果有,就只直接返回让str引用已经存在的"abc"。如下代码实例中s1 == s2是true, s1 == s5是true
  2. String str = new String(“abc”)。当使用这种方式创建字符串时,JVM会直接从堆中开辟一块新的内存来创建这个对象。如下代码中s1 == s3 = false, s1 == s6 = false

代码实例

public class TestString {

    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        String s4 = new String("abc");
        String s5 = "ab" + "c";
        String s6 = "ab" + new String("c");

        System.out.println("s1 == s2 = " + (s1 == s2));
        System.out.println("s1 == s3 = " + (s1 == s3));
        System.out.println("s3 == s4 = " + (s3 == s4));
        System.out.println("s1 == s5 = " + (s1 == s5));
        System.out.println("s1 == s6 = " + (s1 == s6));
        System.out.println("s3 == s6 = " + (s3 == s6));
    }

}

运行结果,因为String类型不能修改字符串。所以String s5 = “ab” + “c”;这句代码实际上会创建三个对象"ab", “c”, “abc”,在这段代码里因为前面已经有定义过String s1 = “abc”;"abc"已经被创建了,所以s5==s1。

s1 == s2 = true
s1 == s3 = false
s3 == s4 = false
s1 == s5 = true
s1 == s6 = false
s3 == s6 = false

Process finished with exit code 0

另外,String类是不可以被继承的,因为String类被final修饰了

StringBuilder和StringBuffer

JAVA还提供了两种可以修改字符串内容的类,他们都是AbstractStringBuilder的子类,并且都被final修饰,都是不可以被继承的,区别在于:

  1. StringBuffer: 线程安全
  2. StringBuilder:线程不安全
StringBuffer

StringBuffer是线程安全的,实现线程安全的方法是用synchronized关键字,可以看到StringBuffer的很多方法都被synchronized修饰了。

StringBuffer可以用appen()方法来拼接字符串,并且不会创建新的对象。

代码实例:

public class TestStringBuffer {

    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer("a");
        StringBuffer sb2 = sb1.append("b");
        System.out.println(sb1 == sb2);
    }

}

运行结果

true

Process finished with exit code 0

可以看一下源码中append是如何实现的:

public AbstractStringBuilder append(String str) {
    if (str == null) {
        return appendNull();
    }
    int len = str.length();
    ensureCapacityInternal(count + len);	// 检查是否需要扩容
    putStringAt(count, str);	// 将字符串填充到尾部
    count += len;
    return this;
}
private final void putStringAt(int index, String str) {
    if (getCoder() != str.coder()) {
        inflate();
    }
    str.getBytes(value, index, coder); // value是StringBuffer类中存字符串的数组
}

可以看到是通过调用String类的getBytes(str.getBytes(value, index, coder);)把str的内容拼接到StringBuffer后面

StringBuilder

StringBuilder是线程不安全的,除此自外跟StringBuffer没有很大的区别

代码实例:

public class TestStringBuilder {

    public static void main(String[] args) {
        StringBuilder sb1 = new StringBuilder("a");
        StringBuilder sb2 = sb1.append("b");
        System.out.println(sb1 == sb2);
    }

}

运行结果

true

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值