接着上一章节的内容。
昨天我回去想了一下,发觉最后的那个特性还是有点问题,我就做了以下的实验。
昨天最后一点属性的简化版:
package com.ray.ch06;
public class Test {
	private final String name = "abcd";
	public String getName() {
		return name;
	}
	public static void main(String[] args) {
		Test test1 = new Test();
		Test test2 = new Test();
		System.out.println(test1.getName() == test2.getName());
	}
}
true
但是,我通过另外一种形式改造一下代码:
package com.ray.ch06;
public class Test {
	private final String name = new String("abcd");//改动的地方
	public String getName() {
		return name;
	}
	public static void main(String[] args) {
		Test test1 = new Test();
		Test test2 = new Test();
		System.out.println(test1.getName() == test2.getName());
	}
}
输出:
false
为什么?
我查找了一些资料,发现,上面的这种情况是编译器的优化机制,编译器对于常量字符串是优化的,但是对于new String这种字符串,没有做出优化,因此,就会出现上面的这两种情况。
参考文章:
(4)final的属性域必须在对象初始化前就已经初始化。
也就是,final的属性域必须在new前就已经初始化
下面是两种初始化方法:
package com.ray.ch06;
public class Test {
	private final int id;
	private final String name;
	{
		id = 0;
	}
	public Test() {
		name = "abcd";
	}
}
因为无论是代码块,还是构造器,都在new之前执行的。
而且,上面使用了空白final属性域,使得这个属性可以在运行时赋值,增加代码的灵活性,还有,一旦初始化了final属性域,它就不能改变值或者引用(这里可以回头看上一章节)。
(5)作为参数的时候,无法改变指向的对象。
package com.ray.ch06;
public class Test {
	private void say(final Value value) {
		// value = new Value();//error
	}
}
class Value {
}
总结:这一章节主要讲述了编译器对于string 的优化,以及final属性域的两个注意点。
这一章节就到这里,谢谢。
-----------------------------------
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/raylee2007/article/details/49613583