Java编程思想: 初始化与清理

构造器与方法

构造器和类名一致, 是由于: 1.保证不和方法名冲突. 2.编译器知道如何进行调用.java

默认构造函数: 1. 没有任何参数. 2.没有任何构造器时会默认生成, 保证类的对象会被初始化. 若是类定义了构造函数, 则不会生成默认构造函数.git

构造函数没有返回值: 因此不能将构造器看作一个方法, 更应该看作建立类实例时必须执行的"代码块"(构造器其实是static方法).github

方法重载: 经过参数列表的不一样进行方法的重载.函数

static: 与类有关, 而与类实例无关. 即static与this无关.this

this指针: 所操做对象的引用.spa

1. 在构造器调用构造器中, 必须使用this来引用构造器, 而非使用类名:指针

public class Test {
  private int i;
  Test() {
    System.out.println("hello");
  }
  Test(int aI) {
//    Test(); //ERROR
    this();
    i = aI;
  }

  public static void main(String[] args) {
    Test t = new Test(11);
  }
}

由于构造器是须要对象来调用的, 即便将构造器当作一个特殊的"方法", 咱们也须要一个实例对象来调用, 而this刚好可知足要求.code

2. 在构造器中, 不能同时调用两次this, 并且this必须放在最起始处, 下例代码有误:对象

public class Test {
	private int i;
	private String s;
	Test(int i) {
		this.i = i;
		System.out.println("int:" + i);
	}
	Test(String s) {
		this.s = s;
		System.out.println("String:" + s);
	}
	Test(int i, String s) {
		this(i);
		// ERROR
		this(s);
	}
	public static void main(String[] args) {
	}
}

3. 不能在其它方法中调用构造函数:生命周期

public void show() {
	// ERROR
	this(0);
    // ERROR
	Test(0, "hello");
}

 

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

垃圾回收的工做方式

引用计数方式回收垃圾: 当有引用链接至对象时, 引用计数加1. 当引用离开做用域或被置为null时, 引用计数减1. 垃圾回收在整个对象的生命周期中查看引用, 若是为0则释放. 但因为存在"循环引用", 则通常现代语言不适用引用计数进行垃圾回收.

Java的对象存活于堆栈静态存储区. 针对存放在堆栈中的对象, 分配新对象仅仅是移动堆栈指针便可. 而因为存在垃圾回收使得堆栈中的对象更加的紧凑, 致使分配存储效率更高.

Java中垃圾回收机制基于: 中止-复制标记-清扫中来回切换的.

中止-复制: 对任何存活于堆栈静态存储区中的对象, 咱们能够查找到全部指向此对象的"活"的引用. 而后在堆栈中分配一个大的内存块, 将"活"的对象复制过去便可.

标记-清扫: 若是垃圾产生量过少, 进行复制会浪费空间. 这时候, 只要将全部"活"的对象进行标记, 所有标记完成后清理未标记的垃圾(这里并未涉及到复制操做).

垃圾回收重要的三点:

1. 对象可能不被垃圾回收: 由于对象不必定在堆栈(使用new建立的对象)和静态存储区中.

2. 垃圾回收并不等于C++中的"析构": "析构"是彻底释放资源, 而"垃圾回收"的主要做用在于整理堆栈空间, 提升分配对象内存的效率. 因此它不必定会释放资源.

3. 垃圾回收只与内存有关.

 

finalize

finalize的工做原理是: 一旦垃圾回收器准备好释放对象占用的存储空间, 将首先调用其finalize方法, 而且在下一次垃圾回收动做发生时, 才会真正回收对象占用的内存.

class Book {
  protected void finalize() {
    System.out.println("book: finalize");
  }
}
public class Ex_10 {
//  protected void finalize() {
//    System.out.println("finalize");
//  }
  public static void main(String[] args) {
    new Ex_10();
    new Book();
    System.gc();
  }
}

这就是为何若是Ex_10中定义finalize, 则System.gc()将不会回收垃圾. 由于对象均在Ex_10中, 不能调用Ex_10的finalize, 从而致使Book的finalize也被抑制.

删除Ex_10中的finalize, 则会调用Book的finalize, 毕竟Book在Ex_10对象以外.

 

初始化

对象的建立过程以下(假设有Dog类):

1. 在实例化对象(new Dog)或者经过Dog调用静态方法/静态域时, Java解释器会定位Dog.class文件.

2. 载入Dog.class后, 执行静态初始化.

3. 在执行new Dog后, 会在堆栈上分配足够大的存储空间.

4. 这块存储空间会被初始化为零, 引用会被初始化为null.

5. 执行字段定义的初始化工做.

6. 执行构造器.

 

习题答案:

https://github.com/leicj/books/tree/master/Java%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3

相关文章
相关标签/搜索