讲解String、StringBuilder、StringBuffer类和CharSequence接口

与字符串相关的三个类和一个接口

在Java中使用的最多的一个操作就是将一个字符串赋值给一个对象了吧。但是又有多少人知道这和字符串相关的类有几个呢?它们都是干什么的呢?本章节就来详谈一下,主要谈论String、StringBuilder、StringBuffer这三个类和CharSequence这个接口。

CharSequence

首先来看看这个接口,Java是一个面向对象、面向接口的语言,一切的类都是基于接口来实现的。那么这个接口是干嘛的呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JqE1YYpm-1602216386694)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201009111526686.png)]

通过官方文档,我们可以知道,该接口出现于JDK1.4,其描述的是一个字符串序列标准操作接口。如果查看它所提供的方法。

int length()									//返回此字符序列的长度。
char charAt(int index)							//返回指定索引处的 char值。
CharSequence subSequence(int start, int end)	//CharSequence字典顺序比较两个 CharSequence实例。
String toString()								//以与此序列相同的顺序返回包含此序列中字符的字符串。

一看方法就更加没意思了,这么一看,好些这个类没什么作用一样?其实它的作用就是为了更加体现Java是一个面向接口的编程的语言而已,而且可以将多个类关联起来。毕竟在方法上使用CharSequence作为接收参数,在一定程度上避免方法的重载了。

String

接下来我们来看看我们最常用的一个类。这个类有点特殊,特殊在于它不需要new就可以直接赋值。这在编写代码的效率上有很大的提升。如果接触过C语言的朋友就知道,C语言是没有字符串类的,一切的操作都要使用char,会显得很麻烦(但是资源消耗更小)。

String大家都会使用了,这里也没什么可说的。本章节主要来说的是String为什么能直接赋值,和它的底层如何操作的,String直接赋值和new String有什么区别。

由于Java在设计的时候考虑到了字符串使用的频率,所以在Java虚拟机上会开辟一个单独的空间,叫常量池。该池保存着String创建的相关字符串,如果说你给不同得变量赋值了一个相同的值,那么实际上它们的引用地址是一样的,也就是说Java并没有为第二个变量开辟新的空间。同时需要知道的是String的创建是一个不可更改的东西。你如果给一个变量赋值以后,那么这个变量的值是不能修改的。你说看到的字符串相加实际上是变量的地址改变了,重新开辟了一块空间出来。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    @Stable
    private final byte[] value;//byte数组
}

通过查看String的源代码可以看到,它继承了刚刚我们说的那个CharSequence接口。同时我们可以看到它创建了一个byte[]数组。该数组就是用来存储数据的。我们对变量赋值的字符串最后都会变成字节存储下来。需要注意的是byte[]数组是在JDK1.9及之后出来的。在之前是使用的char[]数组。这个在面试中经常被提及。

下面开看几个字符串地址比较

String strA = "A";
String strB = "A";
String strC = new String("A");
String strD = new String("A");
System.out.println(strA==strB);
System.out.println(strA==strC);
System.out.println(strC==strD);

这三个输出结果都是ture吗?这个就是String直接赋值于new赋值的区别了。直接赋值相对于将数据存放在常量池中。而new则会开辟空间。当然相应的值也会存放到常量池中,但是它们之间缺少的是地址的改变。new就相对于又重新开辟了一个空间。所以上述的结果为true、false、false。

StringBuilder和StringBuffer

这两个类一起来讲,主要是因为它们之前的区别一句话就可以概括。先看看源代码是如何写的吧。

public final class StringBuilder(StringBuffer)
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{
    @HotSpotIntrinsicCandidate
    public StringBuilder() {
        super(16);//构造一个空的字符串,其默认的容量大小为16,保存都是字节数组的数据。
    }
    @HotSpotIntrinsicCandidate
    public StringBuilder(int capacity) {
        super(capacity);
    }
    @HotSpotIntrinsicCandidate
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }
    public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }
}

上述的第一行哪里的那个括号就表示它们在创建对象的时候是没有区别的。接下来看看官方文档怎么说:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UIDVrEdJ-1602216386701)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201009115904107.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s4SYQh8i-1602216386707)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201009115826181.png)]

它们两个的区别就在于一个是同步一个是异步的。除此之外没有任何区别。同时需要注意的是StringBuffer是在JDK1.0提出的,StringBuilder是JDK1.5提出的。它们的作用就是为了解决String无法更改内容的致命问题(一旦修改就有可能产生大量的垃圾空间)。

该类的使用如下

StringBuilder builder = new StringBuilder();
builder.append("A");
builder.append("A");
builder.append("A");
System.out.println(builder.toString());

总结

上述的接口和类都是为了字符串的操作而提供的,需要注意的是它们提出的版本是不一样,String和StringBuffer是在1.0的时候提出的。CharSequence是在JDK1.4的时候提出的。StringBuilder是在JDK1.5的时候提出的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值