读<<Java解惑>>后的碎嘴子(第五章)

第五章--类问题

46.
public class Confusing {
   	private Confusing(Object o) {
		System.out.println("Object");
	}
	private Confusing(double[] dArray) {
		System.out.println("double array");
	}
	public static void main(String[] args) {
		new Confusing(null);
	}
}
会打印哪个呢?答案是double array,远离了该死的各种数字二进制死循环和try块,本章终于来点面向对象的东西了,这头一条就很让我开眼,重点在于当构造方法发生overload时选择的规律是精确优先于抽象,即double数组类型是一个Object,而Object显然不是一个double数组,当然了,如果在new中声明了具体的类型如Object,那就不会发生这样的现象了
总结:这个规律还是很少有人知道的,和<<effective java>>里一样,大师再一次提醒了慎用overload,但是普通方法还好,构造方法没法起不同的名字,如参数太多,也可以考虑采用builder设计模式

47.代码比较多,原因很简单,本条重点在于说明static域不仅由本类实例共享,其子类实例也会共享同一个static域,不会因为家族类总个数的变化而变化
总结:除了上面的原因,顺便要学会分清has-a和is-a的区别,发扬组合优于继承的光荣传统

48.代码还是比较多,原因还是很简单,对于static方法,不存在override,也不存在晚编联机制(运行时动态决定调用哪个方法,俗称多态),而是用的早编联机制(在编译时就决定了调用哪个方法,根据引用类型来配对而不是多态里的实现类型),这个例子在IDE里显示也会有警告,因为static方法不需要由对象来引用
总结:Java里并不是所有东西都是面向对象的,当然这也没什么不好

49.这条算是比较简单的,涉及了类加载后static初始化的一些顺序问题,尽管在现实中基本看不到这种不入流的singleton
总结:了解一个类加载时,各个元素的加载顺序是每个人必知必会的事情

50.
String s = null;
System.out.println(s instanceof String);
说明instanceof操作符优先会排除null,不管它是何类型的引用
System.out.println(new Test() instanceof String);
编译会失败,引出instanceof另一个很直接的特征:操作符左右要么是同一类型,要么是父子类关系
Test test = (Test) new Object();
编译会成功,但是运行时会扔出熟悉的ClassCastException,和上面的例子形成了很有意思的对比,编译器本条应该查到这个错误却没有,上一条应该理论上返回false但却连编译都不能通过
总结:非要说的话,就是编译器毕竟是死的,其实instanceof还有不少让人犯晕的特点,大师并没有提到

51.基本和49条基本是一回事,涉及了构造方法的调用顺序问题,这里的问题在现实中很难犯,也很容易被察觉
总结:同49条

52.继续顺序的问题,涉及了static块和static域的初始化顺序问题
总结:static块的执行(包括调用了其它的static方法)的整个过程都优先于static域值的初始化

53.本条是一个构造器的技巧用法,并没有涉及到不容易理解的内在机制

54.没什么展示代码和总结的必要了,本条是一个很简单的提示

55.作为本章的最后一条,并没有什么值得深刻记忆的地方
总结:从中引申出5.0中java.util.concurrent包的各主要并发类,需要深刻了解和理解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章