Java中的String类常量池详解
从一个博客上看到的6个题,先看看吧,如果都会了,这部分的知识就掌握的不错啦!输出结果在代码注释后面:
test1:
package StringTest;
publicclass test1 {
/**
* @param args
*/
publicstaticvoid main(String[] args){
String a ="a1";
String b ="a"+1;
System.out.println(a==b);
}//true
}
test2:
package StringTest;
publicclass test2 {
/**
* @param args
*/
publicstaticvoid main(String[] args){
String a ="ab";
String bb ="b";
String b ="a"+ bb; //编译器不能确定为常量
System.out.println(a==b);
}//false
}
test3:
package StringTest;
publicclass test3 {
/**
* @param args
*/
publicstaticvoid main(String[] args){
String a ="ab";
final String bb ="b";
String b ="a"+ bb; //bb加final后是常量,可以在编译器确定b
System.out.println(a==b);
}//true
}
test4:
package StringTest;
publicclass test4 {
/**
* @param args
*/
publicstaticvoid main(String[] args){
String a ="ab";
final String bb = getBB();
String b ="a"+ bb;//bb是通过函数返回的,虽然知道它是final的,但不知道具体是啥,要到运行期才知道bb的值
System.out.println(a==b);
}//false
privatestatic String getBB(){ return"b"; }
}
test5:
package StringTest;
publicclass test5 {
/**
* @param args
*/
privatestatic String a ="ab";
publicstaticvoid main(String[] args){
String s1 ="a";
String s2 ="b";
String s = s1 + s2;//+的用法
System.out.println(s == a);
System.out.println(s.intern() == a);//intern的含义
}//flase true
}
test6:
package StringTest;
publicclass test6 {
/**
* @param args
*/
privatestatic String a =new String("ab");
publicstaticvoid main(String[] args){
String s1 ="a";
String s2 ="b";
String s = s1 + s2;
System.out.println(s == a);
System.out.println(s.intern() == a);
System.out.println(s.intern() == a.intern());
}//flase false true
}
-------------------------------------------------------------------------------------------------
String常量池详解:
1.String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不 可变的(immutable)。String类有一个特殊的创建方法,就是使用""双引号来创建.例如new String("i am")实际创建了2个
String对象,一个是"i am"通过""双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,
一个是编译期,一个是运行期!java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接。运行期调用String类的intern()方法可以向String Pool中动态添加对象。
例1
String s1 = "sss111";
//此语句同上
String s2 = "sss111";
System.out.println(s1 == s2); //结果为true
例2
String s1 = new String("sss111");
String s2 = "sss111";
System.out.println(s1 == s2); //结果为false
例3
String s1 = new String("sss111");
s1 = s1.intern();
String s2 = "sss111";
System.out.println(s1 == s2);//结果为true
例4
String s1 = new String("111");
String s2 = "sss111";
String s3 = "sss" + "111";
String s4 = "sss" + s1;
System.out.println(s2 == s3); //true
System.out.println(s2 == s4); //false
System.out.println(s2 == s4.intern()); //true
结果上面分析,总结如下:
1.单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool中;
2,使用new String("")创建的对象会存储到heap中,是运行期新创建的;
3,使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到String Pool中;
4,使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在heap中;
还有几个经常考的面试题:
String s1 = new String("s1") ;
String s2 = new String("s1") ;
上面创建了几个String对象?
答案:3个 ,编译期Constant Pool中创建1个,运行期heap中创建2个.(用new创建的每new一次就在堆上创建一个对象,用引号创建的如果在常量池中已有就直接指向,不用创建)
String s1 = "s1";
String s2 = s1;
s2 = "s2";
s1指向的对象中的字符串是什么?
答案: "s1"。(永远不要忘了String不可变的,s2 = "s2";实际上s2的指向就变了,因为你不可以去改变一个String,)
--------------------------------------------------------------------------------------------------------------------------------------------------
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是