Linux ·

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";
两种的形式来创建,第一种是

参与评论