ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 聊聊CharSequence及其子类

2020-03-04 11:40:54  阅读:310  来源: 互联网

标签:Java String 子类 str1 CharSequence 字符串 true 常量


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有