**以下内容整理自互联网,仅用于个人学习 **
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略高。