对象导论
--------------------------------------------------------------------------------------
1.将对象想象成 服务的提供者。
2.代码复用,继承和组合的恰当使用。
3. 继承:is a 和 is like a,前者是子类和父类拥有一套完全相同的借口,后者子类不仅拥有父类的
所有接口,且拥有自己的接口(新特性)
--------------------------------------------------------------------------------------
一切皆对象
--------------------------------------------------------------------------------------
1.对象的存储
程序运行时,有六个地方可以存储数据
a. 寄存器:数量有限,编译器根据需求分配,程序感觉不到其的存在。
b. 堆栈:RAM中。通过操作堆栈指针进行快速有效的地分配内存,编译器需要生成相关代码来维护堆栈中的内存分配与释放.
所以垃圾回收器不负责堆该内存区域。Java的引用和基本数据类型存储再堆栈中。抽象数据类型存在在堆中。
c. 堆:RAM中。通用性内存池,所有的Java对象都存放在该区域中。内存分配灵活,释放依赖垃圾回收机制。
注:垃圾回收机制只回收new出来的内存。其他方式或得的内存需要手动释放。
d. 静态存储区域:RAM中。在固定位置存放着程序运行时一直存在的数据。然而Java的对象不会存放在该区域中。
e. 常量存储:直接放在程序的代码内部,一般存放在ROM中。它们永远不会被改变。
f. 非RAM存储:完全存活于程序之外。如流对象或者持久化对象。存储在磁盘或者其他媒介物质上。
2. 基本成员默认值:若类的某个成员是基本数据类型,即使没有初始化,Java也会给它一个默认值。
3. 关于静态Static :通常来说类只是描述一种属性和行为。只有new创建了类的对象才会分配内存。
然而当a.想为特定数据分配一块内存;b.某个方法不和任何对象关联起来---》有了静态。
简单理解为:类数据和类方法。
4. 学习一下 Javadoc
5. 为什么不能以返回值区分重载方法? 因为当为了达到某种效果而调用一个方法,而不关心其返回值。
如: void f(){...} int f(){...} 调用时: f();
6. 垃圾回收器的工作方式
部分Java虚拟机中堆的实现类似一个传送带。每分配一个对象,就前进一个格子。存储空间分配的速度很快。
通过简单地移动“堆指针”到尚未分配的存储区域,效率很高。然而为了避免内存页面的频繁调度,虚拟机中
的堆并不是完全按照传送带的方式工作。这时垃圾回收器发挥了作用。它一面回收内存,一面使堆中的对象紧凑
排列。这样堆指针就可以轻松地移动到更靠近传送带的开始处。从而避免了页面错误。
简而言之,通过垃圾回收器对堆内对象的重新排列,提供了一种高速、有无限空间可分配的堆模型。
工作方式: a. 标记——清扫 b. 停止——复制
--------------------------------------------------------------------------------------
继承
--------------------------------------------------------------------------------------
1. 生成一个类的对象时,变量初始化的顺序:
a. 类加载阶段:加载所有的父类,从最上层的基类开始,先初始化所有的静态变量
b. 所有的类加载完毕,且第一步完成后,开始从最上层的基类开始,初始化所有的非静态成员变量。
c. 从基类开始,逐级调用构造方法。
--------------------------------------------------------------------------------------
多态
--------------------------------------------------------------------------------------
1. 编写构造器的一条有益规则:用尽可能少的方法使对象进入正常状态,如果可以避免的话,尽可能地避免调用其他方法。
(参见:thining in java 构造器内部的多态方法的行为)
2. 继承和组合的选择:用继承表达行为上的差异,用属性表达状态上的变化(组合)。
3. 运行期类型识别RTTI:运行时对类型进行检查的行为。
4. 若不是动态绑定,就不是多态。
--------------------------------------------------------------------------------------
接口和内部类
--------------------------------------------------------------------------------------
1. 接口:方法签名和数据成员(数据成员全部是static和final的 )。
接口用来定义类和类之间的“协议”。
2.内部类:内部类拥有外部类所有成员的访问权限。
3. 为什么会使用内部类实现某个接口,而不是直接用enclosing-class外围类直接实现接口?
a. 内部类可以有效地实现多继承(多个内部类继承自多个类或者抽象类)
b. 每个内部类可以独立地继承自一个实现,无论外围类是否已经继承某个实现,对于内部类都没有影响。
4. 闭包: 内部类是外围类的超集。因为内部类可以访问外部类的所有成员,包括私有成员。或者说内部类是面向对象的闭包。
--------------------------------------------------------------------------------------
异常和错误处理
--------------------------------------------------------------------------------------
1. 异常处理的目标:将错误处理的代码和错误发生的地方相分离。
--------------------------------------------------------------------------------------
运行时类型检查
--------------------------------------------------------------------------------------
1. 运行期识别对象和类信息的两种方式:RTTI和反射
2. 运行期类型识别:当只有一个指向基类的引用时,RTTI可以找出这个对象的确切类型。
RTTI的三种形式:
a. 强制类型转换 Circle c = (Circle)aShape;
b. 通过Class对象来获取运行时所需要的信息。
c. instanceof
3. Class对象:类型信息在运行期保存在Class类型的对象中。当编写并编译了一个类时,就会产生一个class对象
并且被保存在同名.class文件中。运行期,当想生成一个类的对象时,JVM会检查是否加载了该类的class对象,若
尚未加载就根据类名找.class文件并加载。
4. 生成class对象的引用的两种方法:a. Class.forName(); b. 类字面常量 xxx.class
5. RTTI 和反射之间的区别:RTTI在编译器编译期间打开和检查.class文件;
反射在程序运行期间打开和检查.class文件(因为在编译期间.class文件不可获取)
--------------------------------------------------------------------------------------
数组和容器
--------------------------------------------------------------------------------------
1. 数组:注意对象数组和基本数据类型数组的区别。基本数据类型数组直接保存值,对象数组保存对象的引用。
2. 数组复制:对象数组的复制,只是复制引用,是浅拷贝。
3. 数组元素或者容器元素之间的比较:comparator接口
--------------------------------------------------------------------------------------
Java I/O
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
Java nio
--------------------------------------------------------------------------------------
引入NIO的目的: 提高速度,快速移动大量数据
速度的提高来源于使用的结构更接近于操作系统采用的执行I\O的方式:通道和缓冲器。
数据就像是煤矿,通道是通向煤矿的线路。缓冲器是运煤的卡车。能和通道交互的只有缓冲器即ByteBuffer。