JVM指令集3

 分析:JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。

 

 

String a = "ab"; 
String bb = "b"; String b = "a" + bb;  
System.out.println((a == b));  
//result = false

 

  分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。

 

 

String a = "ab";  
final String bb = "b";  
String b = "a" + bb;  
System.out.println((a == b)); 
 //result = true

 

  分析:和[3]中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。

 

 

String a = "ab"; final String bb = getBB();  
String b = "a" + bb;  
System.out.println((a == b));  
//result = false private static String getBB() { return "b"; }

 

  分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面程序的结果为false。通过上面4个例子可以得出得知:

 

 

String s = "a" + "b" + "c";  
就等价于String s = "abc";  
String a = "a"; String b = "b";  
String c = "c";  
String s = a + b + c;

 

  这个就不一样了,最终结果等于:

 

 

StringBuffer temp = new StringBuffer();  
temp.append(a).append(b).append(c);  
String s = temp.toString();

 

  由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:

 

 

public class Test { public static void main(String args[]) { 
 String s = null;  
for(int i = 0; i < 100; i++) { s += "a"; } } }

 

  每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。 如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行 append操作。String对象的intern方法理解和分析:

 

 

public class Test4 {    
private static String a = "ab";     
public static void main(String[] args){    
String s1 = "a";    
String s2 = "b";    
String s = s1 + s2;    
System.out.println(s == a);//false    
System.out.println(s.intern() == a);//true      
}    

 

  这里用到Java里面是一个常量池的问题。对于s1+s2操作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所以s与a的值是不相等的。而当调用s.intern()方法,却可以返回s在JVM常量池中的地址值,因为a的值存储在常量池中,故 s.intern和a的值相等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值