<<Thinking in Java>>从是一本好书, 总的来说这本书讲的非常杂, 方方面面都有讲到, 各个知识点延伸的也不错. 但是一本容量如此之大的书挑不出一点瑕疵是不可能的, 并且作者本人的个人风格在本书中体现的比较重, 导致它在部分细节出现了一些问题, 如果钻研的不是太深入的话其实大多无伤大雅, 因为阅读本书最重要的是领会作者所想表达的编程思想. 但是研究完了JVM之后再来读本书就会发现里面小毛小病有点多, 目前只找到这么多, 之后会再补充:
1. P96 构造器是静态方法
原文是"即使没有显示地使用static关键词, 构造器实际上也是静态方法".
这个问题我在另一篇博文讲到过, 构造器怎么想都不是静态方法, 它是一种只在new或者反射时new instance中调用的特殊方法. 证明就是JVM会给构造器传入一个this指针, 说明构造器是属于该类的一个方法.
这里我想谈谈什么是静态方法, 静态方法虽然是在放在某一个类里面的(Java里面所有东西都在class里面), 但它和所属类的关系仅仅是在加载时体现的, 换句话说, 抛开加载的时机不谈, 静态方法和静态字段其实和这类没半毛钱关系(好吧, 真要说关系的话还是有一点的, 如果是private的话只能本类的"东西"来调用, 这个"东西"可以是对象也可以是静态的东西), 静态方法应该有以下特点(纯本人想法, 仅供参考):
静态方法不属于任何一个对象, 它是全局的, 在我眼中它更像是由JVM持有的方法(其实我也是在学JS的过程领悟到的, JS的全局是window, 那么Java的全局就是JVM啰).
-
因为不会像普通方法那样隐性的传入this指针, 所以静态方法里面不能调用属于该类的fields或方法.
结论: TIJ在胡说八道 = =
2. P143 private和final
原文: "类中所有的private方法都隐式的指定为是final的".
实际上这两个关键字完全没有关系, private指的是只有本类才能调用, final则是不可变(immutable), 反例也非常好找, 在子类中继承final会报错, 但是继承private却不会报错(其实不是继承, 子类和父类是两个方法). 如果private是final的, 那么它也应该会报错才对.
final是不能被重写, 可以被继承的, private也是不能被重写, 可以继承, 但是继承的方法子类访问不到. 只有通过父类public的方法才能访问到, 举个例子:
public class Father {
private int a = 1;
public int getA(){
return A();
}
}
public class Son extends Father{
public static void main(String[] args) {
Father father = new Son();
System.out.println(father.getA());
}
}
可以看出, Son要想访问Father类的私有字段, 需要通过公开方法去访问, 也就是说子类对象是继承了父类的私有字段和方法的.
题外话: 关于final有个非常实用的小技巧, 我是从<<重构>>中学到的, <<重构>>中谈到一个引用最好职责单一, 不要重复赋值, 要是有一个引用前后干了不同的事情那么最好把它们拆开来, 不用前一个引用而是再写个新引用. 那么要怎么判断一个引用有没有重复赋值呢? 非常简单啦, 就是加个final关键词, 如果改过了这个引用编译器就会报错.
3. 第14章 关于RTTI和反射
原文认为RTTI是一种运行时类型识别, Java的多态用的就是RTTI实现的, 而反射则是能在运行期获得.class的类型信息. 这里道理说的都很对, 只是Sun从来没有认为Java有RTTI这个说法. 具体多态是怎么实现的可以看我的这篇文章..
最后是一点点自己的感想, 对于本书的作者, 我是抱着敬仰之心的. 能把这么多内容组织好本身就证明了作者的功力(听说Bruce Eckel的新书On Java8足足写了1300多页...). 写文章本身就是一种设计的过程, 写程序需要设计, 写文章也需要设计. 写多了博客才会发现自己的表达能力十分欠缺, 其实真正缺乏的正是怎么把内容组织好的能力, 所以说需要学习的东西还很多, 不仅仅是技术方面, 还有方方面面 = =.