在我的上一篇小文章《 Java中,String类是final类?》中提到,String是final类。
(1)
String a = "您好";// a是第一个被声明的String
请问,创建变量a时,创建了几个变量?
很多人都知道是1个。(我也是这么认为的)
(2)
那String b = new String("您好");创建了多少个变量呢(不考虑变量a)?
答案是1个或2个。
分析:首先要知道,只要是new一个String,无论之前创建过多少个一摸一样的String对象,此刻,机器都会在堆中分配一个空间来存储新new的string,并且地址是新的,同时会将这个值放在常量池中。而在创建一个新的对象之前,首先运行的是括号中的"您好",此刻,机器首先会在常量池中寻找是否有"您好"这么一个值,若有,则或共用这个值的地址,无需创建新的地址和空间,否则,就会在堆中分配一个新的空间和地址,并在常量池里放入这个"您好"。
(3)
String c = "您好";// 忽略变量a和b
String d = new String("您好");
String e = "您好";
String f = new String("您好");
请问创建了几个变量?
创建c时,首先会遍历常量池中是否存在String类型的"您好"值,若有,则直接引用,无需创建(此刻为创建0个变量),否则就创建一个变量(此刻为创建1个变量)。
创建d时,看好中的"您好"不用创建,是引用c处或引用c所引用的地址,此处创建变量0个。而new String()时,则无论如何都是在堆中开辟一个存储空间和生成一个新地址,所以,此处创建变量0+1个。
创建e时,直接引用c或c所引用的地址,故创建0个变量。
创建f时,看好中的"您好"直接引用c或c所引用的地址,故创建0个变量;直至new String()时,必须开辟一个存储空间和生成新的地址,所以此时创建了0+1个对象。
综合分析,创建的对象有0+1+0+1=2个,或1+1+0+1=3个。
综上所述,同时也是String类明明是Final类,却可以改变值得缘故了(其实是改变地址,导致结果可能改变的。若不明白,请进入《 Java中,String类是final类?》)。
(4)
String g ="a" + "c" + "b";
请问g创建了多少个对象?
分析:String g = "acb" 等同于 String g ="a" + "c" + "b",原因:javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。(原因语句截取自以下文章:《 String 的字符串链接时的内存问题》)。所以是创建了0个或1个对象。
(5)
String h = "a";
String i = h + "b" + "c";
请问i创建了多少个对象?
分析:因为h本身就是一个对象了,所以h+"b"+"c"时,会创建1个新对象,再指向i。
(6)
String j = "a";
String k = "a" + "b" + "c";
请问k创建了多少个对象? 情况和(4)一样。注:本人初学java,若有编写错误之处,还望多多批评指教。