- 浏览: 39121 次
- 性别:
- 来自: 唐山
文章分类
最新评论
一、第一章 对象导论
1、Alan Kay总结了面向对象的五个特性:
1) 万物皆为对象
2) 程序是对象的集合,它们通过发送消息来告知彼此所要做的
3) 每个对象都有自己的由其他对象所构成的存储
4) 每个对象都有其类型
5) 某一特定类型的所有对象都可以接收同样的消息
Booch的描述:对象具有状态、行为和标识。
2、UML:Unified Modelling Language, 统一建模语言。
UML结构
3、通过继承而产生的类型具有等价性,即:导出类与基类具有相同的类型。
4、使基类与导出类产生差异的两种方法:
1) 直接在导出类中添加新方法(is-like-a)
2) 改变现有基类的方法的行为--覆盖(overriding),这叫替代原则,即“纯粹替代”(is-a)
5、多态使用了“后期绑定”的概念,它通过“向上转型”(upcasting)来实现。
6、抽象方法(abstract)只能在抽象类内部创建,当该类被继承时,抽象方法必须被实现,否则继承类仍然是一个抽象类。
7、Java完全采用在被称为堆(heap)的内存池中动态地创建对象。每当想要创建新的对象时,就要使用new关键字来构建此对象的实例。与此不同的是,C++除了在堆中创建对象外,还可以在堆栈中创建对象。
8、Java的单根继承结构,使垃圾回收器的实现变得容易。
二、第二章 一切都是对象
1、存储数据的六个地方
1) 寄存器:编译器决定
2) 堆栈: 堆栈指针若向下移动,则分配新的内存;
若向上移动,则释放那些内存。
对象的引用而非对象存在此。
3) 堆:存放所有的Java对象;
4) 静态存储:RAM中固定的位置;
5) 常量存储:代码区内部;
6) 非RAM存储:如“流对象”和“持久化对象”。
2、虽然Java把一切都可视为对象,但基本类型却是一个特例,它与两种形式存活于Java中:基本类型和对象。
Java Data Type
3、Java基本类型所占存储空间的大小具有不变性,即不随机器硬件架构的变化而变化。
4、两个高精度计算类:BigInteger和BigDecimal。
5、数组也具有数组对象和基本类型数组两种。
6、Java不支持类似C/C++将一个较大作用域的变量“隐藏”起来的做法。
7、当变量作为类的成员使用时,Java才确保给定其默认值,以确保那些是基本类型的成员变量得到初始化,防止产生程序错误。但该规则不适用于局部变量。所以使用一个局部变量前必须对其初始化,否则Java会在编译时返回一个错误。
8、对于static方法,不能简单地通过调用其他非static成员或方法而没有指定某个命名对象,来直接访问非static成员或方法(因为非 static成员或方法必须与某一种特定对象关联)。
9、注释文档(javadoc): /** some comment */
(1) 使用javadoc的方式主要有两种:嵌入HTML和“文档标签”
(2) 文档标签:
独立文档标签:以”@”字符开头的命令,且要置于注释行的最前面(但是不算前导”*”之后的最前面);
行内文档标签:以”@”字符开头,括在花括号内,可以出现在javadoc注释中的内任何地方。
(3) 三种类型的注释文档:
·位于类定义之前
·位于变量定义之前
·位于方法定义之前
(4) javadoc只能为”public”和”protected”成员进行文档注释。”private”和包内可访问成员的注释会被忽略掉。
(5) 不要在嵌入式HTML中使用标题标签,如<hl>或<hr>,因为javadoc会插入自己的标题,而你的标题可能同它们发生冲突。
(6) 一些标签示例
<1>@see: 引用其他类。格式:
@see classname
@see fully-qualified-classname
@see fully-qualified-classname # method -name
<2>{@link package.class#member label} 功能同@see
<3>{@docRoot} 产生到文档根目录的相对路径,用于文档树页面的文档注释中。
<4>@version:
@version version-information
<5>@author:
@author author-information
<6>@since 该标签允许你指定程序代码最早使用的版本
<7>@param 该标签用于方法文档中,形式如下:
@param parameter-name description
<8>@return
@return description
<9>@throws: 描述抛出的异常
@throws fully-qualified-class-name description
<10>@deprecated:该标签用于指出一些旧特性已由改进的新特性所取代。
三、第三章 控制程序流程
1、当关系操作符作用于对象时(<,>,<=,>=,==,!=),关系比较的仅仅是对象的引用。
2、“与”、“或”、“非”操作只可应用于布尔值。不同于C/C++,不可将一个非布尔值当作布尔值在逻辑表达式中的使用。
3、移位操作符:
左移(<<):将操作符左边的操作数向左移动操作符右侧指定的位数(在低位补0)
|-“有符号”右移(>>):将操作符左边的操作数向右移动操作符右侧指定的位数。
| “符号扩展”:若符号为正,则在高位插入0;
右移(>>):< 若符号为负,则在高位插入1。
|
|-“无符号”右移(>>>):“零扩展”:无论正负,都在高位插0
左乘右除准则: 左移一位,相当于乘2^1
右移一位,相当于除2^1
4、非但变量、数值也可以进行类型转换
5、只有for循环才具备在控制表达式里定义变量的能力,其他任何条件语句或循环语句,都不可采用这种方法
6、break和continue语句的规则:
1)一般的continue会退回最内层循环的开头(顶部),并继续执行;
2)带标签的continue会到达标签的位置,并重新进入紧接在那个标签后面的循环;
3)一般的break会中断并跳出当前循环
4)带标签的break会中断并跳出标签所指定的循环,抵达该循环的末尾处。
7、在Java里需要使用标签的唯一理由就是因为有循环嵌套,而且你想从多层嵌套中break或continue。此外,标签要刚好处于要跳转到的循环之前,如:
label1:
outer_iteration{
inner_iteration{
//…
break; //1
//…
continue; //2
//…
continue label1; //3
//…
break label1; //4
}
}
8、switch语句中的“选择因子”的数据类型只能是int或char的整数值,其他类型(float,double,等switch语句将不会工作)。
9、将一个float或double值转型成整数值后,总是将小数部分“砍掉”,而不是四舍五入
10、Math.random()的输出值范围是[0,1)
11、在一个浮点数系统中,可表达的数的总数量是:2(M-m+1)b^(p-1)+1
其中: b-基数(通常是2)
p-精度(尾数中的位数)
M-指数的最大值
m-指数的最小值
IEEE754的规范: M=1023, m=-1022, p=53, b=2
所以能够表示的数的总个数有:
2(1023+1022+1)2^52 = 2((2^10-1) + (2^10-1))2^52
= (2^10-1)2^54
= 2^64 - 2^54
其中,一半的数(指数在[-1022,0]范围内)小于1(包括整数和负数)
第四章、初始化与清理
1、如果用户没有创建一个构造器,java编译器会自动创建一个缺省构造器;但如果用户定义了自己的构造器,编译器则不会再创建默认构造器
2、在构造器中调用构造器时,可以用this关键字调用一个构造器,但却不能同时调用两个。此外,必须将构造器置于最起始处,否则编译器会报错
3、除在构造器中调用外,编译器禁止在其他任何地方中调用构造器
4、finalize()方法(终结处理方法)的工作原理:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存
5、在C++中,对象一定会被销毁(如果程序中没有错误的话);而java里的对象却并非总是被垃圾回收,即:
1) 对象可能不被垃圾回收
2) 垃圾回收并不等于“析构”
3) 垃圾回收只与内存有关
6、java的垃圾回收器是一种“自适应的、分代的、停止-复制(stop-and-copy)、标记-清扫(mark-and-sweep)”式垃圾回收器
7、在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化
8、对象的创建过程:(假设有个名为Dog的类):
1) 当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态字段首次被访问时,java解释器必须查找类路径,以定位 Dog.class文件
2) 然后载入Dog.class(将创建一个class对象),有关静态初始化的所有动作都会被执行。因此,静态初始化只在class对象首次加载的时候进行一次
3) 当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间
4) 这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成默认缺省值
5) 执行所有出现于字段定义处的初始化动作
6) 执行构造器
9、java允许将多个静态初始化动作组织成一个“静态块”进行,如:
class Cups {
static Cup c1;
static Cup c2;
static {
c1 = new Cup(1);
c2 = new Cup(2);
}
Cups() {
System.out.println(“Cups()”);
}
}
同样,对非静态实例初始化也可以采用这种“块”的形式
10、java中的数组有一个只读成员length,表示数组的长度。
第五章、隐藏具体实现
1、访问权限控制的等级,从最大权限到最小权限依次为:
public, protected, 包访问权限(没有关键词), private。
2、编译单元:一个java源代码文件,即.java文件。
3、每个编译单元只能有一个public类,其它类都是低于或等于“包访问权限”的类,用于为主public类提供支持。
4、package和import允许做的,是将单一的全局名字空间分割开,使得无论多少人使用Internet以及java开始编写类,都不会出现名字冲突问题。
5、java中,每个访问权限修饰词(public、protected、private)仅控制它所修饰的特定定义的访问权,而C++中可以控制其后的所有定义,除非另有访问权限修饰词的出现。
6、包访问权限(friendly):当前的包中的所有其他类对那个成员都有访问权限(该成员不指定权限修饰符),但对于这个包之外的所有类,这个成员都是private。
7、public:接口访问权限。
8、private:你无法访问:
除了包含该成员的类之外,其他任何类(包括继承类),都无法访问这个成员
9、protected:用来处理继承,它提供了包访问权限,也就是说,相同包内的其他类可以访问protected元素。而且还表明:就类用户而言,这是private的,但相对于任何继承于此类或其他任何位于同一个包内的类来说,它却可以访问。
10、为了清楚起见,可能会采用一种将public成员置于开头,后面跟着protected、包访问权限和private成员的创建类的形式。
11、类的访问权限:
除内部类外,类既不可以是private的,也不可以是protected的。所以,对于类的访问权限,仅有两个选择:包访问权限或public。
12、static方法就是没有this的方法。在static方法的内部不能调用非静态方法,反过来倒可以。但下面的例子例外:
//: c05: Lunch.java 《java编程思想》3th Edition
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:
class Soup {
private Soup() {}
//(1)Allow creation via static method:
public static Soup makeSoup() {
return new Soup(); // 注:这里的静态方法并不是调用“非静态成员”Soup(),而是用new关键字创建一个实例对象
}
//(2)Create a static object and return a reference
//upon request.(The “Singleton” pattern)
private static Soup ps1 = new Soup();
public static Soup access() { return ps1; }
public void f() {}
}
class Sandwich {
void f() { new Lunch(); }
}
//Only one public class allowed perfile:
public class Lunch {
void test() {
// Can’t do this! Private constractor:
// !Soup priv1 = new Soup();
Soup priv2 = Soup.makeSoup();
Sandwich f1 = new Sandwich();
Soup.access().f();
}
} ///:~
把所有的相应构造器指定为private,从而阻止任何人创建该类的对象,但一个例外是:可以在该类的static成员内部创建。
六、第六章
1、利用现有类型生成新类型(复用代码)的两种方法:组合和继承。
2、同一个编译单元中的每个类都可以创建一个main方法(一般建议这样做,以便测试),只有命令行所调用的那个类的main()方法会被调用(只要这个main()是public,其所属的类是否为public则不用考虑)。
3、编译器会强制你去初始化基类,并要求你要在构造器起始处就要这么做,但它并不监督你必须将成员对象也初始化。
4、垃圾回收器可能永远也无法被调用,即使被调用,它也可能以任何它想要的顺序来回收对象。最好的方法是除了内存以外,不要依赖垃圾回收器去做任何事情。如果需要进行清理,最好是编写你自己的清理方法,但不要依赖finalize()。
5、要使用组合还是继承,一个最清晰的判断办法就是取决于“是否需要从新类向基类进行向上转型”的答案,如果答案是“是”,则使用继承,否则使用组合。
6、final关键字(用到的三种情况:数据、方法和类):
1) final数据:
|作用于基本数据类型:恒定不变的值
a.<|
|作用于对象引用:恒定不变的引用(而非对象本身)
b.空白final:指被声明为final但又未给定初值的字段。但无论什么情况,编译器都确保空白final在使用前必须被初始化。使用空白 final能产生“一个类中的final字段可以做到根据对象而有所不同,却又保持其恒定不变的特性” 的效果。
c.final参数:使无法在方法中更改参数引用所指向的对象
2)final方法:
使用final方法的两个原因:
a.把方法锁定,以防止任何继承类修改它的含义,即确保在继承中使方法行为保持不变,并且不会被覆盖。
b.效率因素:如果将一个方法指明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。但这只是提供一种可能性,执不执行内嵌调用由编译器决定
3)final类:
当将某个类的整体定义为final时(通过将关键字final置于它的定义之前),就表明了不能继承该类,即出于某种考虑,对类的设计永不需要做任何变动,或出于安全的考虑,不希望它有子类。
7、类中所有的private方法都隐式地指定为是final的。
8、“覆盖”只有在某种方法是基类的接口的一部分时才会出现,即必须能将一个对象向上转型为它的基本类型并调用相同的方法。因此,对基类的 private方法不存在“覆盖”行为,它已被有效的“隐藏”,可以当其是“透明”的。
七、第七章 多态
1、面向对象编程语言的三个核心本质:
·数据抽象化(data abstraction)
·继承(Inheritance)
·多态(polymorphism)
2、多态提供了“接口与实现分离”的另一个重要性,能将what(是什么)自how(怎么做)之中抽离。
3、封装(encapsulation)借着“将特征(characteristics)与行为(behaviors)结合在一起”而产生新的数据型别;
实现隐藏(implementation hidden)则籍由“将细目(details)声明为private”而分离出接口(interface)与实现(implementation);
多态则除去了型别之间的耦合关系。
4、java中除了static方法和final方法(private方法属于final方法)之外,其他所有方法都是后期绑定。
要牢牢记住private方法不能被后期绑定,而只能前期绑定。
5、对象类型的确定:(如: Shape s = new Circle)
对于后期绑定:所new的对象类型为具体类型,如Circle
对于前期绑定:声明时的类型,如Shape
6、抽象方法的声明(abstract method):
abstract void f();
抽象类的声明(abstract class):
abstract class class_name {
// …
}
7、对于C++程序员而言,abstract method相当于c++的纯虚函数(pure virtual function)。
8、 有抽象方法的抽象类:一个或多个抽象方法
无抽象方法的抽象类:不含任何抽象方法,仅表示不产生任何实体。
9、构造器的调用顺序:
1)为对象分配存储空间,并初始化为二进制0;
2)调用基类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,等等,直到最底层的导出类;
3)按声明顺序调用成员的初始化方法;
(调用到某类的构造器时进行(既包括基类,也包括导出类))
4)调用导出类构造器的主体。
写成递归的伪代码形式则是:
void constructorOrder(Object obj)
{
1.为对象obj分配存储空间,并将成员初始化为二进制0;
2.constructorOrder(obj.superclass);
3.根据成员的定义进行初始化;
//调用当前类的构造器主体
4.constructor();
}
10、若要作清理工作,则过程和构造时完全相反,即:
1)调用导出类,清理方法的主体;
2)按声明的逆顺序调用成员的清理方法;
3)调用基类的清理方法。
注:上面三个步骤是递归式进行
11、编写构造器时有一条有效的准则:“用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法”。
12、在构造器内唯一能够安全调用的那些方法是基类中的final方法(也适用于private方法,它们自动属于final方法)。
13、用继承进行设计时的一条通用的准则就是:“用继承表达行为间的差异,并用字段表达状态上的变化”。
14、向上转型(upcasting)总是安全的,但向下转型(dowcasting),则需使用类型转换:
如果所转类型是正确的类型,则转型成功;
否则,就会返回一个classCastException异常。
1、Alan Kay总结了面向对象的五个特性:
1) 万物皆为对象
2) 程序是对象的集合,它们通过发送消息来告知彼此所要做的
3) 每个对象都有自己的由其他对象所构成的存储
4) 每个对象都有其类型
5) 某一特定类型的所有对象都可以接收同样的消息
Booch的描述:对象具有状态、行为和标识。
2、UML:Unified Modelling Language, 统一建模语言。
UML结构
3、通过继承而产生的类型具有等价性,即:导出类与基类具有相同的类型。
4、使基类与导出类产生差异的两种方法:
1) 直接在导出类中添加新方法(is-like-a)
2) 改变现有基类的方法的行为--覆盖(overriding),这叫替代原则,即“纯粹替代”(is-a)
5、多态使用了“后期绑定”的概念,它通过“向上转型”(upcasting)来实现。
6、抽象方法(abstract)只能在抽象类内部创建,当该类被继承时,抽象方法必须被实现,否则继承类仍然是一个抽象类。
7、Java完全采用在被称为堆(heap)的内存池中动态地创建对象。每当想要创建新的对象时,就要使用new关键字来构建此对象的实例。与此不同的是,C++除了在堆中创建对象外,还可以在堆栈中创建对象。
8、Java的单根继承结构,使垃圾回收器的实现变得容易。
二、第二章 一切都是对象
1、存储数据的六个地方
1) 寄存器:编译器决定
2) 堆栈: 堆栈指针若向下移动,则分配新的内存;
若向上移动,则释放那些内存。
对象的引用而非对象存在此。
3) 堆:存放所有的Java对象;
4) 静态存储:RAM中固定的位置;
5) 常量存储:代码区内部;
6) 非RAM存储:如“流对象”和“持久化对象”。
2、虽然Java把一切都可视为对象,但基本类型却是一个特例,它与两种形式存活于Java中:基本类型和对象。
Java Data Type
3、Java基本类型所占存储空间的大小具有不变性,即不随机器硬件架构的变化而变化。
4、两个高精度计算类:BigInteger和BigDecimal。
5、数组也具有数组对象和基本类型数组两种。
6、Java不支持类似C/C++将一个较大作用域的变量“隐藏”起来的做法。
7、当变量作为类的成员使用时,Java才确保给定其默认值,以确保那些是基本类型的成员变量得到初始化,防止产生程序错误。但该规则不适用于局部变量。所以使用一个局部变量前必须对其初始化,否则Java会在编译时返回一个错误。
8、对于static方法,不能简单地通过调用其他非static成员或方法而没有指定某个命名对象,来直接访问非static成员或方法(因为非 static成员或方法必须与某一种特定对象关联)。
9、注释文档(javadoc): /** some comment */
(1) 使用javadoc的方式主要有两种:嵌入HTML和“文档标签”
(2) 文档标签:
独立文档标签:以”@”字符开头的命令,且要置于注释行的最前面(但是不算前导”*”之后的最前面);
行内文档标签:以”@”字符开头,括在花括号内,可以出现在javadoc注释中的内任何地方。
(3) 三种类型的注释文档:
·位于类定义之前
·位于变量定义之前
·位于方法定义之前
(4) javadoc只能为”public”和”protected”成员进行文档注释。”private”和包内可访问成员的注释会被忽略掉。
(5) 不要在嵌入式HTML中使用标题标签,如<hl>或<hr>,因为javadoc会插入自己的标题,而你的标题可能同它们发生冲突。
(6) 一些标签示例
<1>@see: 引用其他类。格式:
@see classname
@see fully-qualified-classname
@see fully-qualified-classname # method -name
<2>{@link package.class#member label} 功能同@see
<3>{@docRoot} 产生到文档根目录的相对路径,用于文档树页面的文档注释中。
<4>@version:
@version version-information
<5>@author:
@author author-information
<6>@since 该标签允许你指定程序代码最早使用的版本
<7>@param 该标签用于方法文档中,形式如下:
@param parameter-name description
<8>@return
@return description
<9>@throws: 描述抛出的异常
@throws fully-qualified-class-name description
<10>@deprecated:该标签用于指出一些旧特性已由改进的新特性所取代。
三、第三章 控制程序流程
1、当关系操作符作用于对象时(<,>,<=,>=,==,!=),关系比较的仅仅是对象的引用。
2、“与”、“或”、“非”操作只可应用于布尔值。不同于C/C++,不可将一个非布尔值当作布尔值在逻辑表达式中的使用。
3、移位操作符:
左移(<<):将操作符左边的操作数向左移动操作符右侧指定的位数(在低位补0)
|-“有符号”右移(>>):将操作符左边的操作数向右移动操作符右侧指定的位数。
| “符号扩展”:若符号为正,则在高位插入0;
右移(>>):< 若符号为负,则在高位插入1。
|
|-“无符号”右移(>>>):“零扩展”:无论正负,都在高位插0
左乘右除准则: 左移一位,相当于乘2^1
右移一位,相当于除2^1
4、非但变量、数值也可以进行类型转换
5、只有for循环才具备在控制表达式里定义变量的能力,其他任何条件语句或循环语句,都不可采用这种方法
6、break和continue语句的规则:
1)一般的continue会退回最内层循环的开头(顶部),并继续执行;
2)带标签的continue会到达标签的位置,并重新进入紧接在那个标签后面的循环;
3)一般的break会中断并跳出当前循环
4)带标签的break会中断并跳出标签所指定的循环,抵达该循环的末尾处。
7、在Java里需要使用标签的唯一理由就是因为有循环嵌套,而且你想从多层嵌套中break或continue。此外,标签要刚好处于要跳转到的循环之前,如:
label1:
outer_iteration{
inner_iteration{
//…
break; //1
//…
continue; //2
//…
continue label1; //3
//…
break label1; //4
}
}
8、switch语句中的“选择因子”的数据类型只能是int或char的整数值,其他类型(float,double,等switch语句将不会工作)。
9、将一个float或double值转型成整数值后,总是将小数部分“砍掉”,而不是四舍五入
10、Math.random()的输出值范围是[0,1)
11、在一个浮点数系统中,可表达的数的总数量是:2(M-m+1)b^(p-1)+1
其中: b-基数(通常是2)
p-精度(尾数中的位数)
M-指数的最大值
m-指数的最小值
IEEE754的规范: M=1023, m=-1022, p=53, b=2
所以能够表示的数的总个数有:
2(1023+1022+1)2^52 = 2((2^10-1) + (2^10-1))2^52
= (2^10-1)2^54
= 2^64 - 2^54
其中,一半的数(指数在[-1022,0]范围内)小于1(包括整数和负数)
第四章、初始化与清理
1、如果用户没有创建一个构造器,java编译器会自动创建一个缺省构造器;但如果用户定义了自己的构造器,编译器则不会再创建默认构造器
2、在构造器中调用构造器时,可以用this关键字调用一个构造器,但却不能同时调用两个。此外,必须将构造器置于最起始处,否则编译器会报错
3、除在构造器中调用外,编译器禁止在其他任何地方中调用构造器
4、finalize()方法(终结处理方法)的工作原理:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存
5、在C++中,对象一定会被销毁(如果程序中没有错误的话);而java里的对象却并非总是被垃圾回收,即:
1) 对象可能不被垃圾回收
2) 垃圾回收并不等于“析构”
3) 垃圾回收只与内存有关
6、java的垃圾回收器是一种“自适应的、分代的、停止-复制(stop-and-copy)、标记-清扫(mark-and-sweep)”式垃圾回收器
7、在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化
8、对象的创建过程:(假设有个名为Dog的类):
1) 当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态字段首次被访问时,java解释器必须查找类路径,以定位 Dog.class文件
2) 然后载入Dog.class(将创建一个class对象),有关静态初始化的所有动作都会被执行。因此,静态初始化只在class对象首次加载的时候进行一次
3) 当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间
4) 这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成默认缺省值
5) 执行所有出现于字段定义处的初始化动作
6) 执行构造器
9、java允许将多个静态初始化动作组织成一个“静态块”进行,如:
class Cups {
static Cup c1;
static Cup c2;
static {
c1 = new Cup(1);
c2 = new Cup(2);
}
Cups() {
System.out.println(“Cups()”);
}
}
同样,对非静态实例初始化也可以采用这种“块”的形式
10、java中的数组有一个只读成员length,表示数组的长度。
第五章、隐藏具体实现
1、访问权限控制的等级,从最大权限到最小权限依次为:
public, protected, 包访问权限(没有关键词), private。
2、编译单元:一个java源代码文件,即.java文件。
3、每个编译单元只能有一个public类,其它类都是低于或等于“包访问权限”的类,用于为主public类提供支持。
4、package和import允许做的,是将单一的全局名字空间分割开,使得无论多少人使用Internet以及java开始编写类,都不会出现名字冲突问题。
5、java中,每个访问权限修饰词(public、protected、private)仅控制它所修饰的特定定义的访问权,而C++中可以控制其后的所有定义,除非另有访问权限修饰词的出现。
6、包访问权限(friendly):当前的包中的所有其他类对那个成员都有访问权限(该成员不指定权限修饰符),但对于这个包之外的所有类,这个成员都是private。
7、public:接口访问权限。
8、private:你无法访问:
除了包含该成员的类之外,其他任何类(包括继承类),都无法访问这个成员
9、protected:用来处理继承,它提供了包访问权限,也就是说,相同包内的其他类可以访问protected元素。而且还表明:就类用户而言,这是private的,但相对于任何继承于此类或其他任何位于同一个包内的类来说,它却可以访问。
10、为了清楚起见,可能会采用一种将public成员置于开头,后面跟着protected、包访问权限和private成员的创建类的形式。
11、类的访问权限:
除内部类外,类既不可以是private的,也不可以是protected的。所以,对于类的访问权限,仅有两个选择:包访问权限或public。
12、static方法就是没有this的方法。在static方法的内部不能调用非静态方法,反过来倒可以。但下面的例子例外:
//: c05: Lunch.java 《java编程思想》3th Edition
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:
class Soup {
private Soup() {}
//(1)Allow creation via static method:
public static Soup makeSoup() {
return new Soup(); // 注:这里的静态方法并不是调用“非静态成员”Soup(),而是用new关键字创建一个实例对象
}
//(2)Create a static object and return a reference
//upon request.(The “Singleton” pattern)
private static Soup ps1 = new Soup();
public static Soup access() { return ps1; }
public void f() {}
}
class Sandwich {
void f() { new Lunch(); }
}
//Only one public class allowed perfile:
public class Lunch {
void test() {
// Can’t do this! Private constractor:
// !Soup priv1 = new Soup();
Soup priv2 = Soup.makeSoup();
Sandwich f1 = new Sandwich();
Soup.access().f();
}
} ///:~
把所有的相应构造器指定为private,从而阻止任何人创建该类的对象,但一个例外是:可以在该类的static成员内部创建。
六、第六章
1、利用现有类型生成新类型(复用代码)的两种方法:组合和继承。
2、同一个编译单元中的每个类都可以创建一个main方法(一般建议这样做,以便测试),只有命令行所调用的那个类的main()方法会被调用(只要这个main()是public,其所属的类是否为public则不用考虑)。
3、编译器会强制你去初始化基类,并要求你要在构造器起始处就要这么做,但它并不监督你必须将成员对象也初始化。
4、垃圾回收器可能永远也无法被调用,即使被调用,它也可能以任何它想要的顺序来回收对象。最好的方法是除了内存以外,不要依赖垃圾回收器去做任何事情。如果需要进行清理,最好是编写你自己的清理方法,但不要依赖finalize()。
5、要使用组合还是继承,一个最清晰的判断办法就是取决于“是否需要从新类向基类进行向上转型”的答案,如果答案是“是”,则使用继承,否则使用组合。
6、final关键字(用到的三种情况:数据、方法和类):
1) final数据:
|作用于基本数据类型:恒定不变的值
a.<|
|作用于对象引用:恒定不变的引用(而非对象本身)
b.空白final:指被声明为final但又未给定初值的字段。但无论什么情况,编译器都确保空白final在使用前必须被初始化。使用空白 final能产生“一个类中的final字段可以做到根据对象而有所不同,却又保持其恒定不变的特性” 的效果。
c.final参数:使无法在方法中更改参数引用所指向的对象
2)final方法:
使用final方法的两个原因:
a.把方法锁定,以防止任何继承类修改它的含义,即确保在继承中使方法行为保持不变,并且不会被覆盖。
b.效率因素:如果将一个方法指明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。但这只是提供一种可能性,执不执行内嵌调用由编译器决定
3)final类:
当将某个类的整体定义为final时(通过将关键字final置于它的定义之前),就表明了不能继承该类,即出于某种考虑,对类的设计永不需要做任何变动,或出于安全的考虑,不希望它有子类。
7、类中所有的private方法都隐式地指定为是final的。
8、“覆盖”只有在某种方法是基类的接口的一部分时才会出现,即必须能将一个对象向上转型为它的基本类型并调用相同的方法。因此,对基类的 private方法不存在“覆盖”行为,它已被有效的“隐藏”,可以当其是“透明”的。
七、第七章 多态
1、面向对象编程语言的三个核心本质:
·数据抽象化(data abstraction)
·继承(Inheritance)
·多态(polymorphism)
2、多态提供了“接口与实现分离”的另一个重要性,能将what(是什么)自how(怎么做)之中抽离。
3、封装(encapsulation)借着“将特征(characteristics)与行为(behaviors)结合在一起”而产生新的数据型别;
实现隐藏(implementation hidden)则籍由“将细目(details)声明为private”而分离出接口(interface)与实现(implementation);
多态则除去了型别之间的耦合关系。
4、java中除了static方法和final方法(private方法属于final方法)之外,其他所有方法都是后期绑定。
要牢牢记住private方法不能被后期绑定,而只能前期绑定。
5、对象类型的确定:(如: Shape s = new Circle)
对于后期绑定:所new的对象类型为具体类型,如Circle
对于前期绑定:声明时的类型,如Shape
6、抽象方法的声明(abstract method):
abstract void f();
抽象类的声明(abstract class):
abstract class class_name {
// …
}
7、对于C++程序员而言,abstract method相当于c++的纯虚函数(pure virtual function)。
8、 有抽象方法的抽象类:一个或多个抽象方法
无抽象方法的抽象类:不含任何抽象方法,仅表示不产生任何实体。
9、构造器的调用顺序:
1)为对象分配存储空间,并初始化为二进制0;
2)调用基类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,等等,直到最底层的导出类;
3)按声明顺序调用成员的初始化方法;
(调用到某类的构造器时进行(既包括基类,也包括导出类))
4)调用导出类构造器的主体。
写成递归的伪代码形式则是:
void constructorOrder(Object obj)
{
1.为对象obj分配存储空间,并将成员初始化为二进制0;
2.constructorOrder(obj.superclass);
3.根据成员的定义进行初始化;
//调用当前类的构造器主体
4.constructor();
}
10、若要作清理工作,则过程和构造时完全相反,即:
1)调用导出类,清理方法的主体;
2)按声明的逆顺序调用成员的清理方法;
3)调用基类的清理方法。
注:上面三个步骤是递归式进行
11、编写构造器时有一条有效的准则:“用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法”。
12、在构造器内唯一能够安全调用的那些方法是基类中的final方法(也适用于private方法,它们自动属于final方法)。
13、用继承进行设计时的一条通用的准则就是:“用继承表达行为间的差异,并用字段表达状态上的变化”。
14、向上转型(upcasting)总是安全的,但向下转型(dowcasting),则需使用类型转换:
如果所转类型是正确的类型,则转型成功;
否则,就会返回一个classCastException异常。
发表评论
-
Tomcat热部署原理
2012-05-19 20:49 1198一. ... -
java 并发实践
2012-03-23 11:02 0java并发编程实践笔记 1, 保证线程安全的三种方法: ... -
Map sort
2010-12-02 11:09 1812可能会遇到这样的情况,我可能要对Map<key,valu ... -
Java 解析 xml
2010-07-20 10:59 6941.介绍 1)DOM(JAXP Crimson解析器 ... -
java 编码
2010-07-01 22:06 657现代计算机采用的都是 ... -
Class文件格式解析
2010-07-01 21:40 889http://www.blogjava.net/javafan ... -
java中byte转换int时为何与0xff进行与运算
2010-07-01 21:29 908[转]java中byte转换int时为何与0xff进行与运算 ... -
java 的InputStream和OutputStream的理解
2010-06-21 15:10 1913(转)java 的InputStream和OutputStre ... -
java-email(转)
2010-03-23 15:50 926最近在项目中用到发送 ... -
UNICODE与 UTF-8的转换详解
2010-03-19 10:18 4802转载请注明出处: http://www.ins1000.cn/ ... -
java中hashcode()和 equals()的详解[转]
2010-03-18 14:34 714java中hashcode()和 equals() ... -
细说java的util中的集合类
2010-03-03 14:54 728线性表,链表,哈希表是常用的数据结构,在进行Java开发时,J ... -
String 创建
2010-03-01 10:52 774package com; import org.junit.T ... -
java字符串连接
2010-02-01 17:22 1540注:引用http://www.blogjava.net/nok ... -
java
2010-01-06 16:53 643【转】JNDI的详细介绍(09-03-27) 收藏 看到这篇关 ...
相关推荐
《Think in Java》是Java编程领域的一本经典著作,由Bruce Eckel撰写,深受程序员喜爱。这本书通过深入浅出的方式讲解了Java语言的核心概念和技术,包括面向对象编程、数据结构、算法以及网络编程等多个方面。"Think...
《Think in Java》是Bruce Eckel的经典编程教材,它深入浅出地讲解了Java语言的基础概念和高级特性。源码整理则为读者提供了实践和学习的机会,帮助理解书中的示例和理论。以下是对《Think in Java》源码中一些重要...
java think in java (英文第四版)至今为止 被认为是java教程之中权威作品之一
《Think in Java 3》是一本深受欢迎的Java编程指南,由Bruce Eckel撰写,它以其详尽的解释和丰富的示例闻名。这本书是许多Java初学者和专业开发者的重要参考资料,旨在帮助读者深入理解Java语言的核心概念和机制。...
《Think in Java》是 Bruce Eckel 的经典著作,它深入浅出地讲解了Java编程语言的核心概念和技术。这本书强调理解编程思想,而不仅仅是学习语法。练习题是学习过程中的重要部分,它们帮助我们巩固理论知识,提升实际...
《Think In Java 4》是Java编程领域里一本极具影响力的著作,由资深程序员 Bruce Eckel 编著。这本书以其深入浅出的讲解方式和全面的知识覆盖而闻名,被誉为Java学习者的经典读物。中文版的完美高清版本为国内读者...
Think in java 源码构建编译
《Think in Java 中文第四版》是学习Java编程的经典之作,由Bruce Eckel撰写,它深入浅出地讲解了Java语言的核心概念和技术。本部分主要涵盖的是书籍的第二部分,通常涉及面向对象编程的深入探讨,包括类、对象、...
Think in Java(美)Bruce Eckel 著 陈昊鹏 译 引言 同人类任何语言一样,Java为我们提供了一种表达思想的方式。如操作得当,同其他方式相 比,随着问题变得愈大和愈复杂,这种表达方式的方便性和灵活性会显露无遗。 ...
《Think in JAVA 编程思想》是Java编程领域的一本经典著作,由Bruce Eckel撰写。第四版作为该书的最新版本,包含了作者对Java语言深入的理解和丰富的编程经验,旨在帮助读者理解面向对象编程的核心理念,并提升编程...
think in java 第四版 源码以及作业 eclipse版本 包含jar包 可以直接导入eclipse
《Think in Java》是Java编程领域的一本经典著作,作者是Bruce Eckel。第11章的主题是“持有对象”,这一章主要探讨了如何在Java中创建和管理对象,包括对象的引用、对象的生命周期、类与对象的关系,以及如何通过...
think in java think in java think in java think in java think in java think in java
《Think in Java 4》是Java编程领域的一部经典之作,由Bruce Eckel撰写,它以其深入浅出的讲解方式和丰富的示例代码深受程序员喜爱。这个压缩包包含的就是这本书的全部源代码,旨在帮助读者更好地理解和实践书中所...
抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善基础类 1.5.2 等价和类似关系 1.6 多形对象的互换使用 1.6.1 动态绑定 ...1.11 Java和因特网
《Think in Java》第四版是一本被广大Java程序员推崇的书籍,它被认为是每个Java开发者必读的经典之作。这本书不仅适合初学者,对有一定经验的程序员来说,也是一本很好的参考书籍。书中内容详尽,解释精准,例子...
Think In Java (第四版) java编程思想(第四版) 实例 Jar包(包括javassist.jar xom-1.2.10.jar net.mindview.jar swt.jar javaws.jar tools.jar)
《Think in Java中文版》是Java编程领域里一本极为经典的著作,由Bruce Eckel撰写,中文版由国内多位专家翻译,旨在帮助读者深入理解Java语言的精髓和思想。这本书不仅覆盖了Java的基础语法,还涉及面向对象编程的...
《Think in Java》是Java编程领域的一本经典著作,由Bruce Eckel撰写,被誉为Java学习者的开山之作。这本书深入浅出地介绍了Java语言的核心概念和技术,为读者提供了全面而深刻的Java编程知识体系。 首先,我们要...