CH5 初始化与清理

C++引入了构造器的概念,JAVA在此基础上,额外提供了“垃圾回收器”。

5.1 用构造器确保初始化

由于构造器的名称必须与类名相同,所以“每个方法首字母小写”的编码风格并不适用于构造器。

从概念上讲,“初始化”与“创建”是彼此独立的,而在JAVA中,“初始化”与“创建”捆绑在一起。

构造器是一种特殊类型的方法,因为它没有返回值。这与返回值为空(void)明显不同。对于空返回值,尽管方法本身不会自动返回什么,但仍然可选择让它返回别的东西。构造器则不会返回任何东西(new表达式确实返回了对新建对象的引用,但构造器本身并没有返回值)

5.2 方法重载

的确,方法重载对于构造器来说是必须的,所以《Thinking in Java》这本书很合理地将方法重载的内容安排在了构造器之后。

5.2.1 区分重载方法

每个重载的方法都必须有一个独一无二的参数类型列表。即,靠参数类型列表的不同来区分同名的不同方法。甚至参数顺序的不同也可以区分,但这样会使得代码难以阅读和维护。

5.2.2 涉及基本类型的重载

基本类型能从一个“较小”的类型自动提升至一个“较大”的类型,基于此情形,对于方法重载,如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升。Char类型略有不同,如果无法找到恰好接受char参数的方法,就会把char直接提升至int型。
如果传入的实际参数大于重载方法声明的形式参数,则需要做显式的窄化转换。

5.2.3-“以返回值区分重载方法是行不通的”。

5.3默认构造器(略)

5.4 this关键字
This关键字表示对当前对象的引用,只能在方法内部使用。

若要在构造器中调用其他的构造器,可用this。
通常this表示对当前对象的引用,而在构造器中,如果为this添加了参数列表,那么就有不同的含义。这将产生对符合此参数列表的某个构造器的明确调用。
但,尽管可以用this调用一个构造器,却不能调用两个。此外必须将调用置于起始处,否则编译器会报错。
并且,构造器只能从另一个构造器内部调用,构造器以外的方法不可以调用构造器。

在staitc方法的内部不能调用非静态方法。

5.5 清理:终结处理和垃圾回收

finalize()方法在垃圾回收之前执行。但并非析构函数。JAVA中并没有析构函数。
注意一下三点:
    1.对象可能不被垃圾回收;
    2.垃圾回收并不等于“析构”;
    3.垃圾回收只与内存有关

System.gc()用于强制进行终结动作。

5.6成员的初始化

JAVA尽力保证:所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。(类成员用默认值)
如:
  
void  f() {
        
int i;
        i
++// Error
}

// 错误,i未被初始化。


若类的数据成员是基本数据类型,会有默认初始值。

5.6.1 指定初始化:
如:
int  i  =   999 ;
byte  b  =   47 ;
short  s  =   0xff ;


也可以通过调用某个方法来提供初始值,但要注意参数的初始化顺序,即方法的参数必须已经初始化了。

5.7 构造器的初始化

可以利用构造器进行成员的初始化,但要牢记:无法阻止自动初始化的进行,它将在构造器被调用之前发生。

5.7.1 初始化顺序

我觉得这一部分是重点!
在类的内部,变量定义的先后顺序决定了初始化的顺序。而即使变量定义散布于方法啊定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。

5.7.2 静态数据的初始化

无论创建多少个对象,静态数据都只占有一份存储区域——再次提醒。
静态对象会在非静态对象之前得到初始化。

总结一下对象的创建过程,假设有个名为Dog的类:
1、    当要创建Dog对象,或者Dog类的静态方法、静态域被访问时,Java解释器先定位Dog.class文件;
2、    载入Dog.class(这将创建一个Class对象),有关静态初始化的所有动作执行。因此,静态初始化只在Class对象首次加载的时候进行一次;
3、    当用new Dog()创建对象时,首先将堆上为Dog对象分配足够的空间;
4、    这块空间被清零;
5、    执行处于字段定义处的初始化;
6、    执行构造器。

5.7.3 显式的静态初始化
  public   class  Spoon {
        
static int i;
        
static{
            i 
= 47;
        }

}


5.7.4 非静态实例初始化
与上例显示的静态初始化一样,只是少了static关键字

5.8 数组初始化

一直对数组有一种畏惧心理,数组究竟是什么?书上第98页下面有一句话精确的给出了描述:“数组只是相同类型的、用一个标识符名称封装到一起的一个对象序列活基本类型数据序列。数组是通过方括号下标操作符[]来定义和使用的”。——忘记曾经学的哪门子语言了,用的是圆括号,似乎是VB,导致我混淆了很长一段时间。
要定义一个数字,只需在类型名后加上一个方括号即可:int[] a1;
在定义的时候不允许指定数组的大小,因为到现在为止,定义的只是对数组的引用,为数组在堆上分配空间必须写初始化表达式,如int[] a1 = {1, 2, 3, 4};
将数组赋值给另一个数组实际上赋值的是引用。

所有的数组都有一个固定的成员length,而下标是从0 ~ length – 1。

使用new创建数组元素:int[] a = new int[4]        //尽管int是基本数据类型
如果创建的是一个非基本数据类型的数组,则是一个引用数组。

另外几种创建方式:
Integer[] a  =   {new Integer(1), new Integer(2), 3,} ;
Integer[] b 
=   new  Integer[] {new Integer(1), new Integer(2), 3,} ;


5.8.1可变参数列表
如:static void printArray(Object… args){
        …
}
这是Java SE5 之后的新特性,等同于原先的用数组作为的参数:static void printArray(Object[] args){}

有了这种可变参数,就不需要显式地编写数组语法了,当你指定参数时,编译器会为你去填充数组。所以最终或得的仍然是一个数组!


5.9 枚举类型
enum 也是Java SE5 的一个新特性。
public   enum  Spiciness {
    NOT, MILD, MEDIUM , HOT, FLAMING
}

这里创建了一个名为Spiciness的枚举类型,具有5个具名值。

enum会自动创建toString()方法,ordinal()方法:表示某个特定enum常量的声明顺序,以及static values()

enum与switch语句绝配,减弱了switch本身的选择因子必须是int 或 char 那样的整数值的限制。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值