• 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中提供了许多的操作字符串的方法,这就需要大家自行去多多练习。

  • 相关阅读:
    信息安全算法
    另类装载问题
    分治法快速排序
    动态规划最长公共子序列
    java网络编程1
    Jndi和会话bean
    EJB初探
    JSF初探
    简单计算器
    关于坐火车
  • 原文地址:https://www.cnblogs.com/ring2/p/11074100.html
Copyright © 2020-2023  润新知