String知识

**以下内容整理自互联网,仅用于个人学习 **

String源码分析

一、String类

String是被final修饰的类,也就是说String类是不可变类。String类实现了Serializable, Comparable, CharSequence接口。

Comparable接口有compareTo(String s)方法,CharSequence接口有length(),charAt(int index),subSequence(int start,int end)方法。

二、String属性

String类中包含一个不可变的char数组来存放字符串,一个int型的变量hash用来存放计算后的hash值。

/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0

/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

三、构造函数

//不含参数的构造函数,一般没什么用,因为value是不可变量
public String() {
    this.value = new char[0];
}

//参数为String类型
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

//参数为char数组,使用java.utils包中的Arrays类复制
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

//从bytes数组中的offset位置开始,将长度为length的字节,以charsetName格式编码,拷贝到value
public String(byte bytes[], int offset, int length, String charsetName)
        throws UnsupportedEncodingException {
    if (charsetName == null)
        throw new NullPointerException("charsetName");
    checkBounds(bytes, offset, length);
    this.value = StringCoding.decode(charsetName, bytes, offset, length);
}

//调用public String(byte bytes[], int offset, int length, String charsetName)构造函数
public String(byte bytes[], String charsetName)
        throws UnsupportedEncodingException {
    this(bytes, 0, bytes.length, charsetName);
}

四、String常用方法

boolean equals(Object anObject)

public boolean equals(Object anObject) {
    //如果引用的是同一个对象,返回真
    if (this == anObject) {
        return true;
    }
    //如果不是String类型的数据,返回假
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        //如果char数组长度不相等,返回假
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            //从后往前单个字符判断,如果有不相等,返回假
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            //每个字符都相等,返回真
            return true;
        }
    }
    return false;
}

switch能否用String做参数?

Java5以前只能用byte、short、char、int,Java5开始引入枚举,Java7开始引入String。


equals与==的区别

  • 比较基础数据类型:这种情况下,==比较的是他们的值是否相等。
    引用间的比较:在这种情况下,==比较的是他们在内存中的地址,也就是说,除非引用指向的是同一个new出来的对象,此时他们使用==去比较得到true,否则,得到false。

  • 字符串的对比使用equals()代替==操作符

注意:equals是Object类提供的方法之一。每一个Java类都继承自Object类,所以每一个对象都具有equals方法。Object类中定义的equals方法是直接使用==运算符比较两个对象的,所以没有覆盖equals方法的情况下equals和==运算符一样,比较的是引用。String类的equals方法正是因为被覆盖,所以才能被用于比较字符串。


String、StringBuffer与StringBuilder的区别

  • String
    String是不可变类,意味着String引用的字符串内容是不可改变的。String类是线程安全的。
String s = "ABC";  
System.out.println("s = " + s);    
s = "123";  
System.out.println("s = " + s);  

上述代码执行后打印出
s=ABC
s=123

从打印结果来看,s的值确实改变了。那怎么会说String类是不可变类呢?其实这里存在一个误区,**s只是一个String对象的引用,并不是对象本身。**也就是说,s只是一个引用,它指向了一个具体的对象,当s=“123”; 这句代码执行过之后,又创建了一个新的对象“123”, 而引用s重新指向了这个心的对象,原来的对象“ABC”还在内存中存在,并没有改变。
  • StringBuffer和StringBuilder
    StringBuffer和StringBulder类表示的字符串对象可以直接进行修改。StringBuilder是JDK1.5引入的,它和StringBuffer的方法完全相同,区别在于它是非线程安全的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer略高。

你可能感兴趣的:(String知识)