深入【Java】底层细节知识点(3)String类的深入理解
![Rank: 8](images/default/star_level3.gif) ![Rank: 8](images/default/star_level3.gif)
- UID
- 1066743
|
![](http://images.eccn.com/silabs/silicon_chip_980x60_202203.jpg)
深入【Java】底层细节知识点(3)String类的深入理解
四、S
tring
类的深入理解
了解一个类最好的方式就是看源码
public final class String implements java.io.Serializable, Comparable<String>, CharSequence{ /** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count; /** 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; 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);}public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } char buf[] = new char[count + otherLen]; getChars(0, count, buf, 0); str.getChars(0, otherLen, buf, count); return new String(0, count + otherLen, buf);}public String replace(char oldChar, char newChar) { if (oldChar != newChar) { int len = count; int i = -1; char[] val = value; /* avoid getfield opcode */ int off = offset; /* avoid getfield opcode */ while (++i < len) { if (val[off + i] == oldChar) { break; } } if (i < len) { char buf[] = new char[len]; for (int j = 0 ; j < i ; j++) { buf[j] = val[off+j]; } while (i < len) { char c = val[off + i]; buf = (c == oldChar) ? newChar : c; i++; } return new String(0, len, buf); } } return this;}} 更多的不再展示。
从以上的源码中获得信息:
- String是final类,这意味着,这个类不能被继承,也不可有子类,其中的方法默认都是final方法
- String类是通过char数组来保存字符串的
- String类对字符串的操作都是对新字符串操作。也就是说,S
tring
对象一定被创建就不会改变,任何改变操作都不会改变原字符串,而是生成了新的对象
字符串常量池:
- 每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串不可变,所以常量池中一定不存在两个相同的字符串
- 静态常量池和运行时常量池。
- 静态常量池,即.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。
- 运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。
虽说,字符串的比较,我们使用equals方法,但用==号就可以看出,a和b指向的同一个对象。而new以后就产生新的对象。
如果使用equals比较三者,得出的结果,肯定都是true
由于c是new出来的,所以产生了两个对象,一个是栈区中的c,另一个就是堆中的123,他们的引用关系是c->123->123(常量池中的)
也就是说,尽管c是创建在堆中,但其value还是常量池中的123
当我们对字符串,进行拼接,替换等操作时,会创建一个新的对象来操作,之后旧的对象,就会被当作垃圾回收。
|
|
|
|
|
|