Java基础之String

一、字符串的比较

在开始讲解String之前先看看以下代码:

        String a = new String("123");
        String b = new String("123");
        String c = "123";
        String d = "123";
        String e = a.intern();
        System.out.println(a==b);//false  
        System.out.println(c==d);//true   
        System.out.println(a==c);//false  
        System.out.println(a==e);//false  
        System.out.println(c==e);//true           

  以上代码是简单的字符串的比较,后面的注释给出了相应的结果。下面我们来对执行结果进行相应的解释,首先执行a==b的结果很显然是false,因为是通过new关键字创造了两个不同的对象,这两个

对象都存储在堆空间中,a和b具有不同的引用,故为false,这里还要插一嘴:

String a = new String("123");

  当执行到该代码时,实际上创建了两个对象,一个是由于String Pool 中并没有“123”这个字符串字面量,故会在String Pool中创建这个字符串对象指向“123”这个字符串字面量。另一个就是通过new关键字创建在heap 堆中的对象了。

  接着来说说c==d,在这之前说一说String Pool,我们知道它代表的是字符串常量池,保存着像“123”这种的字符串字面量,在编译时期就确定被加入到String Pool中。很显然,c、d都是引用的String Pool中唯一存在的字符串字面量“123”,所有结果为true。a==c的结果也很显然了,一个的引用在堆中,一个的引用在String Pool中 故结果为false。现在来说一说a==e的比较结果,说这个之前我们要先了解了解intern()这个方法:

  当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用。

  现在我们再来看看,首先a.intern()的返回结果是String Pool中的“123”,而a引用的对象在堆中,故为a==e false. 所以最后一个c==e 就很好理解了,都是引用的String Pool中的“123”,故为true。

二、String类介绍

  String 被声明为 final,因此它不可被继承。在 Java 8 中,String 内部使用 char 数组存储数据。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
}

  在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 coder 来标识使用了哪种编码:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final byte[] value;

    /** The identifier of the encoding used to encode the bytes in {@code value}. */
    private final byte coder;
}

  value 数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。

  说到String类,我们就会联想到StringBuffer和StringBuiler,String被定义为final,而StringBuffer和StringBuilder没有被定义为final,故为可变的。StringBuffer主要用来对字符串进行追加、拼接最后还是产生一个对象,而使用String对字符串进行拼接就显得有些繁琐并浪费空间。而StringBuilder和StringBuffer的唯一区别在于StringBuffer是线程安全的,使用了synchronized关键字来保证安全,这样也使得StringBuffer的效率低于StringBuider.

 总结: 

  1. 可变性

  • String 不可变
  • StringBuffer 和 StringBuilder 可变

  2. 线程安全

  • String 不可变,因此是线程安全的
  • StringBuilder 不是线程安全的
  • StringBuffer 是线程安全的,内部使用 synchronized 进行同步

  String中提供了许多的操作字符串的方法,这就需要大家自行去多多练习。

 

转载于:https://www.cnblogs.com/ring2/p/11074100.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值