String的部分源码
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
- 由源码可以看出String类被final修饰,所以String类不能被继承。
- 由private final char value[];可以看出,String字符串的底层其实就是char类型的数组,因为被final修饰,所以char数组的地址不能更改。但是地址上的值通过反射是可以修改的,在下面会有例子。
面试题1:
以下代码的输出结果是多少?
public class TestString { public static void main(String[] args){
// 不可变字符串
String s =" a b ";
s.trim();
System.out.println("!"+s+"!");
}
}
答案:! a b !
- 由String的源码可以看出,String底层的存储结构是被final修饰的char数组,所以是不可变的,也就是说String是不可变的字符序列(指的是地址不可变),所以使用trim()方法是不可以改变原来的String字符串的,得到的是一个新的字符串。
- 如果将s.trim();换成s = s.trim();,那么最后的输出结果就是!a b!(去除的两端的空格)。
扩展: - String的trim() 方法只能去除英文状态下的空格(半角空格),不能去除中文下的空格(全角空格)。
怎么改变String字符串的值?
- String字符串的地址值(就是在内存中的位置)虽然不可以改变,但是地址上的值是可以通过反射机制来进行修改的。
- 代码如下:
public class TestFinal {
public static void main(String[] args) throws Exception {
// 不可变字符串
String s = "a b"; //“a b”
Class<String> stringClass = String.class;
Field value = stringClass.getDeclaredField("value");
value.setAccessible(true);
char[] cs = (char[])value.get(s);
cs[1] = 'd';
System.out.println(s);
}
}
输出结果:adb
网友评论