您的位置:首页 > 编程语言 > Java开发

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

2015-07-28 10:05 197 查看
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());

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: