String知多少——Java特种兵上的例子

package tezhongbing;


import org.junit.Assert;
import org.junit.Test;


/**
 * 编译器优化一定是在编译阶段能确定优化后不会影响整体功能,类似于final引用,这个引用只能被赋值一次,但是它无法确定赋值的内容是什么。
 * 只有在编译阶段能确定这个final引用赋值的内容,编译器才有可能进行编译时优化,
 * 而在编译阶段能确定的内容只能来自于常量池中,例如int、long、String等常量,
 * 也就是不包含new String()、new Integer()这样的操作,因为这是运行时决定的,
 * 也不包含方法的返回值。因为运行时它可能返回不同的值,带着这个基本思想,对于编译时的优化理解就基本不会出错了。
 * @author sunniwell
 *
 */
public class StringTest {
/**
* a虽然是由三个常量值+起来的,但它的值仍然是确定的、可预测的,所以虚拟机在编译阶段就进行了优化a=ab1
*/
@Test
public void test1(){
String a = "a"+"b"+1;
String b = "ab1";
Assert.assertTrue(a == b);
}

private String getA(){return "a";}

/**
* 变量b是由变量a和常量"b"+起来的,虽然变量a指向的是个常量"a",但它的引用还是可能发生改变,所以变量b的表达式不能被优化为一个常量。
* 变量c因为有了final修饰符,编译器就认为它是不可变的,所以d的值就是可预测的,因此会对d进行优化。
* 变量e是由一个函数和常量+起来的,编译器并不会去看函数内部做了什么,所以也不会被优化。
*/
@Test
public void test2(){
String a = "a";
final String c = "a";
String b = a+"b";
String d = c+"b";
String e = getA()+"b";
String compare = "ab";
Assert.assertFalse(b==compare);
Assert.assertTrue(d==compare);
Assert.assertFalse(e==compare);
}

/**
* 常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。
* 它包括了关于类,方法,接口等中的常量,也包括字符串常量,是JVM的一块特殊的内存空间。
* 它里面的常量是全局唯一的。
* 当调用intern()方法时,JVM会在常量池中通过equals方法查找是否存在等值的String。

*/
@Test
public void test3(){
String a = "a";
String b = a+"b";
String c = "ab";
String d = new String(b);
Assert.assertFalse(b==c);
Assert.assertFalse(c==d);
Assert.assertTrue(c==d.intern());
Assert.assertTrue(b.intern()==d.intern());
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值