Thinking in Java笔记之初始化清理

第四章 初始化清理
1. 重载函数的参数匹配。
 a. 传入的实际参数类型小于方法中声明的形式参数类型,实际参数的类型就会被提升。但char除外,如果没有恰好接受char的方法,就会把char提升为int。
 b. 传入的实际参数类型大于方法中声明的形式参数类型,就得显示的类型转换,否则会报错。但这种窄化转换会丢失信息。

2. 在构造器中调用构造器
 如果一个类中有多个构造器,你可以在一个构造器中调用另一个构造器。
 如:
 
 注意事项:
 a. 你可以用this调用构造器,但你不能用同样的方法构造两个构造器;
 b. 构造器调用必须置于最起始处;
 c. 除构造器外,其他任何方法都不能调用构造器。
 
3. 终结处理和垃圾回收
 垃圾回收器只知道释放那些经new分配的内存。对于不用new分配的内存可在类中定义一个finalize()方法清理。它是在垃圾回收器准备回收时被调用。但它并不等于析构。
 a. 对象不一定总被回收。(一般只有在内存耗尽时才运行垃圾回收)
 b. 垃圾回收并不等于析构。
 c. 垃圾回收只与内存相关。
 
4. 不能将finalize()作为通用的清理方法。
finalize()只用于在分配内存时用了类C的做法,如调用了c/c++的代码,而里面又用了malloc()等函数来分配内存,就得在finalize()方法中调用free()等方法清理。

public class Flower {
  int petalCount = 0;
  String s = new String("null");
  Flower(int petals) {
   petalCount = petals;
   System.out.println("Constructor w/ int arg only, petalCount=  "
                      + petalCount);
  }

  Flower(String ss) {
   System.out.println("Constructior w/ String arg only, s=" + ss);
   s = ss;
  }
 
  Flower(String s, int petals) {
    this(petals);
    //! this(s); //Can't call two!
    this.s = s;  //Another use of "this"
    System.out.println("String & int args");
  }
 
  Flower() {
    this("hi", 47);
    System.out.println("default constructor (no args)");
  }
 
  void print() {
   //! this(11); //Not inside non-constructor!
   System.out.println("petalCount = " + petalCount + " s = " + s);
 }
 
 public static void main(String[] args) {
   Flower x = new Flower();
   x.print();
 }
}

 

5. 终结条件
终结条件可理解为程序要关闭时必须满足的条件。如一个程序中的一个对象打开了一个文件,那么在程序结束时所有打开的文件应该被关闭。
finalize()方法一个重要的用途就是验证终结条件。
如:

本例所有的Book对象在被当作垃圾回收前都应该被签入(check in)。但在main()中有一本没有。如果没有finalize()来验证条件,这个错误将很难发现。

6. 类的每个基本类型数据成员保证都会有一个初始值
boolean  false
char   0
byte   0
short  0
int    0
long   0
float   0.0
double  0.0

7. 类里定义一个对象引用时,如果不将其初始化,此引用就会得null值。

8. 与c++不同,类成员变量可在其定义的地方为其赋值。


9. 构造初始化无法阻止自动初始化的进行,它将在构造器被调用前发生。
class Couunter {
   int i;
   Counter() {
     i = 7;
   }
}

这里i 先是0再是7

10. 在类的内部,变量会在任何构造器被调用前得到初始化。

11. 初始化的顺序
初始化的顺序是先"静态"对象再"非静态对象"。

12. 对象的创建过程(假设有个Dog类)
1) 当首次创建类为Dog类的对象时(构造器可看成是静态方法),或者Dog类的静态方法/静态字段首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。
2) 然后载入Dog.class。有关静态初始化的所有动作都会执行。因此,静态初始化只在class对象首次加载的时候执行一次。
3) 当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。 4)这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成了却省值,而引用则被设置成了null。
5) 执行所有出现于段定义处的初始化动作。
6) 执行构造器。

13. 静态子句
Java允许将多个静态初始化动作组织成一个特殊的“静态子句”如:
class Spoon {
static int i;
static {
i = 47;
}
}
像static{}中的代码块就是静态子句。该代码块中的语句只执行一次。

14. 非静态实例初始化子句
和静态子句一样,非静态实例初始化也能写成代码块。如:
Dog d1;
Dog d2;
{
d1 = new Dog();
d2 = new Dog();
}

{}中的就是非静态实例初始化子句。

15. 如果数组里的元素不是基本数据类型,那么必须使用new。否则使用数组中的空引用就会产生“异常” 

 

class Book {
  boolean checkedOut = false;
  Book(boolean checkOut) {
  checkedOut = checkOut;
}

void checkIn() {
  checkedout = false;
}

public void finalize() {
  if(checkedOut)
    System.out.println("Error: checked out");
  }
}

public class TerminationCondition {
  public static void main(String[] args) {
    Book novel = new Book(true);
    //Proper cleanup
    novel.checkIn();
    // Drop the reference, forget to clean up
    new Book(true);
    //Force garbage collection & finalization
    System.gc();  //强制进行终结动作
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值