一、介绍
String:不可变的Unicode字符序列
例如:"Java" 就是4个Unicode字符J,a,v,a组成的
Java没有内置的字符串类型,而是在标准的Java类库中提供了一个预定义的类String.每个用双引号括起来的字符串就是String类的一个实例.
当使用+,实际是产生新的对象
StringBuilder:可变字符序列,线程不安全,效率高(常用)
StringBuffer:可变字符序列,线程安全,效率低
(使用循环拼接字符串时,一定要用StringBuilder或者StringBuffer其中的一个)
二、查看String的一小部分源码
1 2 3 4 5 6 | The <code>String</code> class represents character strings. All * string literals in Java programs, such as <code> "abc" </code>, are * implemented as instances of this class . * <p> * Strings are constant; their values cannot be changed after they * are created. |
String类存在于java.lang包中。上述大概意思:String是一个字符串,String的字面量也是String的一个实例。String它的值在创建以后是不能变的.....
1 2 3 4 5 | public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; |
可以看出外部类是不能直接访问到这个value属性的,这个char value[]不可变
以下是String的部分构造器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //默认构造器,当写下了String str =new String();的时候,其实内部是给了一个长度为0的char数组给value public String() { ...省略部分.... this .value = new char [ 0 ]; } //可以传递一个字符串,则直接把传递的字符串赋给了value public String(String original) { ...省略部分.... this .value = v; } /** *也可以传递一个字符数组,例如:可以像下面这样 *char[] c = {'a','b','c'}; *String str = new String(c); */ public String( char value[]) { int size = value.length; this .offset = 0 ; this .count = size; this .value = Arrays.copyOf(value, size); } |
String重载了很多构造器,不一一查看了。
String的一些常用方法源码:还有很多其他的,不一一介绍了,使用起来都很简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | //length是直接返回的count public int length() { return count; } //isEmpty是直接判断count是否等于0 public boolean isEmpty() { return count == 0 ; } //charAt是取char[] value中相应索引的值,count不在范围抛出数组索引越界异常 public char charAt( int index) { if ((index < 0 ) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } return value[index + offset]; } //substring public String substring( int beginIndex) { return substring(beginIndex, count); } //开始索引小于0,大于当前对象总长度,或者结束索引大于总长度,都抛出越界异常 //否则,开始等于0,结束等于总长度,则重新new一个string对象 public String substring( int beginIndex, int endIndex) { if (beginIndex < 0 ) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > count) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } return ((beginIndex == 0 ) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value); } //常用的equals方法(重写了父类的equals方法),是先比较对象是否为同一个对象。然后比较其内容是否都相等。 public boolean equals(Object anObject) { if ( this == anObject) { //首先比较当前对象和传来的对象是不是同一个对象 return true ; } if (anObject instanceof String) { //如果传来的对象是String的一个实例 String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0 ) { //数组每个元素对应比较 if (v1[i++] != v2[j++]) //如果有一个元素不相等,返回false return false ; } return true ; } } return false ; } |
length、isEmpty、charAt、substring等等的就不做测试了,主要测试equals方法
1 2 3 | String str = new String( "abcd" ); String str2 = str; System.out.println(str.equals(str2)); //返回结果:true,因为str和str2都指向了同一个new String("abcd");对象 |
1 2 3 4 5 | String str = new String( "abcd" ); String str2 = new String( "abcd" ); System.out.println(str.equals(str2)); //返回结果:true,此时str和str2指向的不是同一个对象,但是内容相等 //但是如果直接==的话就是false System.out.println(str==str2); //因为不是同一个对象 |
三、总结
1、String是由final修饰的class,不可修改。内部的属性都是private的,不给外部访问。
2、内部的主要操作就是操作的char value[]数组,这个value其实是可以修改的,但是jdk中没有提供接口供你修改。
3、字符串比较需要使用equals方法,两个对象比较使用==
4、部分常用方法,还有一些concat、replace、replaceFirst、replaceAll、split、toLowerCase、toUpperCase、trim、valueOf等等的方法
1 2 3 4 5 6 7 8 9 10 11 12 | //长度:直接返回count属性 public int length() //是否空:直接return count==0 public boolean isEmpty() //根据指定索引获取字符:如果index<0或者index>count都抛出*StringIndexOutOfBoundsException,否则直接返回char数组中对应的值 public char charAt( int index) //如果传来的和调用的是同一个对象,返回true //然后遍历比较,如果传来对象的其中一个值跟调用的对象不等,就返回false public boolean equals(Object anObject) //substring先判断beginIndex < 0,beginIndex < 0,beginIndex >endIndex都会抛出异常 //否则(beginIndex == 0) && (endIndex == count)成立的话直接返回this,不成立则new String public String substring( int beginIndex, int endIndex) |
5、值得一提的是,String的toString方法是直接返回的this
6、String对象个数问题:
1 2 3 4 5 6 7 8 | String str= "a" ; //总共一个对象a String str2= new String( "a" ); //总共两个对象:一个new String,一个a String str= "a" ; //这里一个对象 for ( int i= 0 ;i< 10 ;i++){ str = str + i; //这里每循环一次都会创建一个对象 } //以上执行完会出现11个对象 |