《Java 编程思想》,原版英文书为《Thinking in Java》,全书800多页的容量,基本覆盖了所有的 Java 知识(包括那些高级特性),该书也赢得了全球程序员的广泛赞誉。最近仔细看了这本书,感觉确实是一本经典好书,现打算作此读书笔记整理,随时记录一些阅读过程中发现的技术要点、难点,以便巩固 Java 知识,同时方便以后随时查阅。
1. 对象导论
- has-a —— 组合,is-a —— 继承。
- 所有可以发送给基类对象的消息同时也可以发送给导出类对象,即导出类与基类具有相同的类型、等价性。
- 把将导出类看作是它的基类的过程称为向上转型(upcasting)。
- Java 是单根继承结构,终极基类就是 Object。
2. 一切都是对象
- 尽管一切都看作是对象,但操纵的标识符实际上是对象的一个“引用”。
- 栈用于存放一些对象引用、基本变量的值,堆用于存放所有的 Java 对象。
- 堆不同于栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。
- 9种基本类型:boolean(不明确)、char(16-bit)、byte(8-bit)、short(16-bit)、int(32-bit)、long(64-bit)、float(32-bit)、double(64-bit)、void(不明确)。(数值类型均有正负号)
- Java 有一个垃圾回收器,用来监视用 new 创建的所有对象,并辨别那些不会再被引用的对象。
- 方法名和参数列表(一起称为“方法签名”)唯一地标志出某个方法。
3. 操作符
- 赋值操作的是一个对象的引用。
- == 和 != 比较的是对象的引用。
- 除非在自己的新类中覆盖 equals() 方法,否则不可能表现出我们希望的行为。
- 以二进制形式显示结果可以使用 Integer 和 Long 类的静态方法 toBinaryString()。
- 移位操作符只可用来处理整数类型(基本类型的一种)。左移位(<<),低位补0;有符号右移位(>>),符号扩展(正补0,负补1);无符号右移位(>>>),高位补0。
4. 控制执行流程
- Java 里唯一用到逗号操作符(注意不是逗号分隔符)的地方就是 for 循环的控制表达式。
- return 关键词:一方面指定一个方法返回值,另一方面它会导致当前的方法退出,并返回那个值。
- 在 Java 里需要使用标签的唯一理由就是因为有循环嵌套存在,而且想从多层嵌套中 break 或 continue。
- switch 语句支持的类型:可以隐式转换到 int 的数据类型(如byte、short、char;long不行),String 类型(1.7以后)以及 Enum 类型。
5. 初始化与清理
- 区分重载方法:每一个重载的方法都必须有一个独一无二的参数类型列表。
- 如果已经定义了一个构造器(无论是否有参数),编译器就不会帮你自动创建默认构造器。
- this 关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。
- static 方法就是没有 this 的方法。
- 垃圾回收的特点:1.对象可能不被垃圾回收。 2.垃圾回收并不等于“析构”。 3.垃圾回收只与内存有关。
- 垃圾回收器查找存活对象:从栈和静态存储区开始,遍历所有的引用。就能找到所有“活”的对象。
- Java 虚拟机会进行监控,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”方式;同样,Java 虚拟机会跟踪“标记-清扫”的是效果,要是堆空间出现很多碎片,就会切换回“停止-复制”方式。这就是“自适应”技术。—— “自适应的、分代的、停止-复制、标记-清扫”式垃圾回收器。
- 惰性评估,即编译器只在必要的时候才编译代码。
6. 访问控制权限
- 访问权限等级由大到小依次为:public、protected、包访问权限和 private。(注意:protected 也提供包访问权限)
- package 语句,必须是文件中除注释以外的第一句程序代码。
- 把数据和方法包装进类中,以及具体实现的隐藏,常共同被称作封装。
- 类既不可以是 private 的,也不可以是 protected 的。(内部类是特例)
7. 复用类
- 使用组合还是继承:是否需要从新类向基类进行向上转型?需要,则继承。
- 对于基本类型,final 使数字恒定不变;而对于对象引用,final 使引用恒定不变
- 使用 final 方法的原因:1.方法锁定,以防任何继承类修改它的含义。2.效率,编译器会将 final 方法的所有调用转为内嵌调用。
8. 多态
- 多态,也称作动态绑定、后期绑定或运行时绑定。
- Java 中除了 static 方法和 final 方法(private 方法属于 final 方法)之外,其他所有的方法都是后期绑定。
- 一条通用的准则是:“用继承表达行为间的差异,并用字段表达状态上的变化”。
9. 接口
- 抽象方法,即仅有声明而没有方法体。
- 包含抽象方法的类叫做抽象类。
- 接口的方法只能是抽象的和公开的,且自动的是 public 方法,不能有构造器,可以包含域,但是这些域隐式地是 static 和 final 的。
- 使用接口的核心原因:为了能够向上转型为多个基类型(以及由此而带来的灵活性)。
- 抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。
- 接口最吸引人的原因之一就是允许同一个接口具有多个不同的具体实现。它的体现形式通常是一个接受接口类型的方法。
- 接口中的任何域都自动是 static 和 final 的,所以接口就成为了一种很便捷的用来创建常量组的工具。(在没有 enum 之前)
10. 内部类
- 内部类还拥有其外围类的所有元素的访问权。
- 每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
- 内部类生成的 .class 文件的命名规则:外围类的名字,加上 “$”,再加上内部类的名字。(如果是匿名内部类,编译器会简单地产生一个数字作为其标识符)
11. 持有对象
- System.out.print(c);(c为某个类的对象)该方法将打印类名,后面跟随该对象的散列码的无符号十六进制表示(这个散列码是通过 hashCode() 方法产生的)。
- 迭代器通常被称为轻量级对象:创建它的代价小。
- Iterator 的真正威力:能够将遍历序列的操作与序列底层的结构分离。或者说,迭代器统一了对容器的访问方式。
- 四种容器:Map、List、Set 和 Queue。链接
12. 通过异常处理错误
- 同 Java 中其他对象的创建一样,将使用 new 在堆上创建异常对象。
- Throwable 这个 Java 类被用来表示任何可以作为异常被抛出的类。Throwable 对象可分为两种类型(指从 Throwable 继承而得到的类型):Error 用来表示编译时和系统错误(除特殊情况外,一般不用你关心);Exception 是可以被抛出的基本类型,在 Java 类库、用户方法以及运行时故障中都可能抛出 Exception 型异常。
- finally 子句需要清理的资源:已经打开的文件或网络连接,在屏幕上画的图形,甚至可以是外部世界的某个开关。
- C++ 和 Java 都是强静态类型语言,即编译时就做类型检查的语言。
- 反射和泛型就是用来补偿静态类型检查所带来的过的限制。
- 至理名言:好的程序设计语言能帮助程序员写出好程序,但无论哪种语言都避免不了程序员用它写出了坏程序。
13. ···
注:图片来自于Dribbble。
————————原创文章,未经许可,请勿转载!!!————————