初学Java经常会误认为String是java基本类型,实际上String并非Java的8个基本类型,String本质上是对char数组的封装
下面对String源码进行分析
public final class String implements java.io.Serializable, Comparable<String>,
CharSequence {
}
String类实现了Serializable,Comparable和CharSequence三个接口
Serializable是标记接口,用于标记实现此接口的类可以被序列化
Comparable:
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
那么Comparable接口到底有什么用呢?简单的说,如果你想一个类的对象支持比较(排序),那就必须要实现Comparable接口。此接口内部只有一个要重写的方法int compareTo(T o),这个方法对两个字符串按字典排序的方式进行比较,返回两个字符串中第一个不同的字符的 ascii码差值
CharSequence:
是一个字符char序列,实现此接口的类有CharBuffer,String,StringBuffer(线程安全),StringBuilder(线程不安全),那么CharSequence接口到底有什么用呢?
就拿String中的方法contains来说,注意它的参数是CharSequence s,由于StringBuffer和StringBuilder都实现了CharSequence,那么就可以直接用StringBuffer和StringBuilder传参,可以减少一次转换
下面开始说说String类的私有变量和构造函数
/*
这个私有变量说明了String最重要的两个点:
1.char value[]表明String实质是以字符数组的形式存放的
2.final关键字表明String一旦创建就无法改变,对于String的
重新赋值都是重新划分内存空间,创建了新的String
*/
private final char value[];
//缓存String的hashCode值 默认为0
private int hash;
//Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
public class Demo {
public static void main(String[] args) throws Exception {
String str1 = "abcd";
System.out.println(str1);// abcd
String str2 = new String();
System.out.println(str2);//
String str3 = new String("abcd");
System.out.println(str3);// abcd
char[] c = { 'a', 'b', 'c', 'd', 'e', 'f' };
String str4 = new String(c);
System.out.println(str4);// abcdef
String str5 = new String(c, 2, 3);
System.out.println(str5);// cde
int[] a = { 65, 66, 67, 68, 97, 98 };
String str6 = new String(a, 2, 3);
System.out.println(str6);// CDa
byte[] b = { 65, 66, 67, 68 };
String str7 = new String(b, 1, 3, "ASCII");
System.out.println(str7);// BCD
String str8 = new String(b, 1, 3);
System.out.println(str8);// BCD
String str9 = new String(b, "ASCII");
System.out.println(str9);// ABCD
String str10 = new String(b);
System.out.println(str10);// ABCD
StringBuffer sb1 = new StringBuffer("abcd");
String str11 = new String(sb1);
System.out.println(str11);// abcd
StringBuilder sb2 = new StringBuilder("abcde");
String str12 = new String(sb2);
System.out.println(str12);// abcde
}
}
接下来分析String的核心方法
import java.util.Date;
public class Demo2 {
public static void main(String[] args) throws Exception {
String str1 = "abcde";
System.out.println(str1.length());// 5 返回String的长度
System.out.println(str1.isEmpty());// false 判断String是否为空
System.out.println(str1.charAt(1));// b 返回value[index]
System.out.println(str1.codePointAt(1));// 98
System.out.println(str1.codePointBefore(1));// 97
/*
Java中超出char编码范围(65536)的unicode字符由两个char组成
codePointCount()是准确计算unicode(而不是char)字符的数量的方法
*/
System.out.println(str1.codePointCount(1, 3));// 2 返回1-3之间的码点值
System.out.println(str1.offsetByCodePoints(1, 3));// 4 返回从1偏移3个码点后的索引
char[] c = new char[10];
str1.getChars(0, 3, c, 0);// 把value[0-3)的值复制到c中(从0开始存放)
for (char d : c) {
System.out.print(d + " ");// a b c
}
System.out.println();
byte[] b1 = str1.getBytes("ASCII");
for (byte b : b1) {
System.out.print(b + " ");// 97 98 99 100 101
}
System.out.println();
byte[] b2 = str1.getBytes();
for