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());
}
}
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());
}
}
相关文章推荐
- (23) 深入理解Java:注解(Annotation)基本概念||自定义注解入门||及注解处理器
- Spring MVC 教程,快速入门,深入分析
- java+poi读取和存储excel表格内容
- Spring MVC+Mybatis+Maven+Velocity+Mysql
- eclipse 开发playframework
- java多线程
- java 判断三个字符串中是否有相等,去掉重复字符串输出
- javaweb-url /
- springmvc缓存
- 打开eclipse 异常弹出对话框 Subversion Native Library Not Available的解决
- iOS注释标记(参考javadoc)
- 简单的Java打字游戏
- [Java]对字符串中的每个单词个数进行统计
- java常用的23种设计模式《转》
- java playframework
- Java对数组的复制
- 我的Java开发学习之旅------>Base64的编码思想以及Java实现
- draw something in Java DEMO
- java 对象序列化和对象反序列化操作时的版本兼容性问题
- 设置Eclipse中的tab键为4个空格的完整方法