1.什么string?
string 用于表示字符串,在Java中定义在Java.lang 包下,string 是不可变的。
2.为什么string 被设计为不可变?是不是真的不可变呢?
首先为什么说string 被设定为不可变对象?
主要从两个方面考虑:
(1)安全
安全是首要考虑的因素,由于string 被很多地方用作参数传递,比如url以及一些Java 方法,如果可变的话会引起巨大的安全漏洞,而且string 不可变的还保证了在多线程共享一个string 对象的安全性。
(2)性能
由于string 常量池的存在,可以保证一个string对象被多个变量名指向,节省了推内存的空间;同时string 字符串被用作缓冲hash码,string 的不变性保证了hash码的唯一性,意味着不用每次去计算新的hash码,节省了内存空间。
string 一定是不可变的吗?
string 是可以通过反射机制来改变的,代码如下:
String str = "abcd";
public void updateStr(){
try {
Class<?> clazz = str.getClass();
//输出原本的str
System.out.println("输出原本的内容:"+str);
Field value = clazz.getDeclaredField("value");
System.out.println("value:"+value);
value.setAccessible(true);
//返回属性的类型
char[] temp = (char[]) value.get(str);
temp[0] = 'g';
System.out.println("反射之后的str:"+str);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Test22 test22 = new Test22();
test22.updateStr();
}
结果:
输出原本的内容:abcd
value:private final char[] java.lang.String.value
反射之后的str:gbcd
3.请谈一下string、stringBuilder、stringbuffer 三者之间的区别?
string 是不可变类,每次操作string都会创建新的对象。stringbuilder 和stringbuffer是可变类,
stringbuilder是线程不安全的,stringbuffer线程安全的。在单线程的情况下,stringbuilder 比 stringbuffer的效率要高。
4.String str = new String(“abcd”);请问这句代码创建了几个对象?
如果字符串常量池中已经有“abcd“这个对象,那么只会在堆内存中创建一次这个对象;如果常量池
中没有这个对象,就会在堆内存和常量池中同时创建这个对象,会创建两次。
5.下面这段代码输出什么:
String a = “a”;
StringBuffer b = new StringBuffer(a);
System.out.println(a.equals(b));
输出false,string 的equeals 会做类型判断。
6.下面代码输出什么?
String s1 = “abc”;
String s2 = new String(“abc”);
s2.intern();
System.out.println(s1 ==s2);
输出false,intern()方法将返回从字符串池中的字符串对象的引用,但因为我们没有分配到S2,S2没有变化,如果该第三行代码为s2 =
s2.intern(),则输入true。