编程语言
首页 > 编程语言> > Java 聊聊CharSequence及其子类

Java 聊聊CharSequence及其子类

作者:互联网

CharSequence

CharSequence是char值的可读序列。 该界面提供统一的,只读访问许多不同类型的char序列。 

实现类

其中最重要的也是最常用的就是 String、StringBuilder和StringBuffer。这三字子类都是用来处理字符串的,但是他们之间还有有一定差别的。

String

从源码上来看是实现了 Serializable 序列化接口、Comparable 可比较接口和CharSequence 字符序列接口,String 底层是用的  final char 数组进行存储的,所以字符串一旦确定不可改变。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
    ......
}

因为字符串比较常用,所以对其进行了优化,可以直接用 "..."来表示字符串。
在 JVM 堆中有一个字符串常量池,每创建一个字符串时都会判断字符串常量池中有没有这个字符串,如果有的话直接将地址指向字符串常量池中的地址,如果没有的话在字符串常量池中新增一个字符串,然后在指向新增的字符串地址。

所以在进行大量的字符串操作时不推荐使用 String ,因为字符串常量池中会有很多无用的字符串,造成空间浪费和GC频繁

Stirng 也没有进行锁机制,所以多线程中是不安全的,慎用。

简单小测试

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = "ab"+"c";
String str5 = new String("ab")+new String("c");;
System.out.println("1."+(str1 == str2)); //true or false
System.out.println("2."+(str1 == str3));//true or false
System.out.println("3."+(str1 == str3.intern())); //true or false
System.out.println("4."+(str1 == str4)); //true or false
System.out.println("5."+(str1 == str5)); //true or false

1. str1 和 str2 都是使用直接创建,所以str1 在字符串常量池中,str2 检测常量池中有"abc",所以直接指向常量池的字符串,所以答案是 true

2. str1指向常量池,str3 使用 new 关键字创建一个对象,所以答案是 false

3. String.intern()方法:当调用intern方法时,如果池已经包含与equals(Object)方法确定的相当于此String对象的字符串,则返回来自池的字符串。 否则,此String对象将添加到池中,并返回对此String对象的引用。 所以答案是 true

4. 该行代码重点说明一下,jvm对其有优化处理,也就是在编译阶段就会将这两个字符串常量进行拼接,所以和第一个的答案一样 true

5. 因为 new String 后会在堆中生成一个对象,而 str1 指向字符串常量,所以答案为 fasle

StringBuilder

从源码上来看是继承了 AbstractStringBuilder抽象类,实现了Serializable 序列化接口和CharSequence 字符序列接口。而AbstractStringBuilder底层维护了一个 char数组,这个数组不会放入字符串常量池中。

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{
    ....
}

添加字符串的时候会

所以StringBuilder进行字符串操作的时候速度最快,在单线程中推荐使用,但是在多线程环境中要慎用。

StringBuffer

从源码上来看好像和 StringBuilder 差不多,就多了一个缓存。

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{

    /**
     * transient:在序列化是以transient修饰的变量不会被序列化。
     * 该属性在调用ToString时记录下最近一次value值,而在修改这个value时,会将这个置为null
     */
    private transient char[] toStringCache;
    ....

}

但是你在往下翻的时候会发现大量的 synchronized 的关键字。

所以 StringBuffer 和 StringBuilder 最大的区别就是线程安全。但是使用的是 synchronized 关键字,多线程中只允许一个线程进入,保证安全了,但是效率又下降了。

标签:Java,String,子类,str1,CharSequence,字符串,true,常量
来源: https://blog.csdn.net/cong____cong/article/details/104647867