注意:
String a=new String("hawk");//一个是生成实例对象//这个实在堆得内存上创建一个String对象.
String s="abc";//一个是生成引用//这样声明的字符串会放在字符串的缓冲池中,当然只是String特有的缓冲池,一般引用对象和基本数据类型对象都没有,
//它是java中唯一不需要new 就可以产生对象的途径
///s = "Initial Value";
s = new String("Initial Value");
对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题
你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改
堆包含方法区和new出来的对象,而常量池在方法区里,两个也是有联系的,
那样的字符串常量就是存放在常量池的,通过new 出来的字符串对象就是存在于堆空间里的,stringBuffer才是新建存在于缓冲区的字符串对象
String类型可以对字符串常量直接相加的表达式进行优化,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
补充:String的intern使用
存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的 一个方法;
当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,
如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用
String s0= "kvill";
String s1=new String("kvill");
String s2=new String("kvill");
System.out.println( s0==s1 );
System.out.println( "**********" );
s1.intern();
s2=s2.intern(); //把常量池中"kvill"的引用赋给s2
System.out.println( s0==s1);
System.out.println( s0==s1.intern() );
System.out.println( s0==s2 );
结果为:
false
**********
false //虽然执行了s1.intern(),但它的返回值没有赋给s1
true //说明s1.intern()返回的是常量池中"kvill"的引用
true
说明用intern的方法必须重新把引用赋值给string对象的引用,这样才可以赋值引用成功.
intern的作用是在字符串运行期间,在.class文件中添加常量
有什么不对的地方,欢迎大家给提意见.