一、Java基础
什么是字符串常量池?
Java中的字符串常量池(String Pool)是存储在Java堆内存中的字符串池;
String是java中比较特殊的类,我们可以使用new运算符创建String对象,也可以用双引号(”“)创建字串对象。
如果池中没有字符串字面量“Cat”,那么首先在池中创建,然后在堆空间中创建,因此将创建总共2个字符串对象。
之所以有字符串常量池,是因为String在Java中是不可变(immutable)的,它是String interning概念的实现。字符串常量池也是亨元模式(Flyweight)的实例。
字符串常量池有助于为Java运行时节省大量空间,虽然创建字符串时需要更多的时间。
当我们使用双引号创建一个字符串时,首先在字符串常量池中查找是否有相同值的字符串,如果发现则返回其引用,否则它会在池中创建一个新的字符串,然后返回新字符串的引用。
如果使用new运算符创建字符串,则会强制String类在堆空间中创建一个新的String对象。我们可以使用intern()方法将其放入字符串常量池或从字符串常量池中查找具有相同的值字符串对象并返回其引用
String为什么是不可变的?
value,offset和count这三个变量都是private的,并且没有提供setValue, setOffset和setCount等公共方法来修改这些值,所以在String类的外部无法修改String。也就是说一旦初始化就不能修改, 并且在String类的外部不能访问这三个成员。此外,value,offset和count这三个变量都是final的, 也就是说在String类内部,一旦这三个值初始化了, 也不能被改变。所以可以认为String对象是不可变的了。
那么在String中,明明存在一些方法,调用他们可以得到改变后的值。这些方法包括substring, replace, replaceAll, toLowerCase等。例如如下代码:
String a = "ABCabc"; System.out.println("a = " + a); a = a.replace('A', 'a'); System.out.println("a = " + a);
那么a的值看似改变了,其实也是同样的误区。再次说明, a只是一个引用, 不是真正的字符串对象,在调用a.replace('A', 'a')时, 方法内部创建了一个新的String对象,并把这个心的
String s = new String("xyz");究竟产生了几个对象,从JVM角度谈谈
答:一个或者两个; 声明:s不是对象,不是对象,不是对象,s是指针引用 判断 : if("xyz"在常量池中存在){ 只会在堆中创建一个new String("xyz") ;一个对象 } else { 会现在常量池中创建一个“xyz”,然后在堆中创建一个new String("xyz");两个对象 }