一、

finalize()是Object的接口,作用是回收对象,一般由GC自动调用来回收对象,调用后,下个GC周期会回收这个class实例(不建议使用),System.gc()可以显示的调用GC来触发finalize();

二、

对象创建的过程:
1首次创建或者调用某个class的静态方法/静态域(包括构造器)时,java定位查找class的路径。
2然后载入class并且有关的静态初始化执行且只执行这一次。
3创建对象的时候,分配内存,且内存会被清零,对象所有数据为null,
4执行所有初始化动作,执行构造器。

其实情况是,如果调用了静态方法但是并没有创建对象,则仅初始化静态代码块(这里似乎是按照静态代码块顺序来初始化,静态方法在静态变量和代码块后执行),如果使用new关键字创建对象,则首先执行静态代码块,然后执行动态代码块,然后执行构造器。

这里有个情况,使用反射获得Class并且使用newInstance获得实例,还是会调用到无参构造方法,如果该class并没有无参构造方法,则抛出InstantiationException。代码和结果如下:

public class InitialValues{
    static Cups cups = new Cups();
    public static void main(String[] args) {
        System.out.println("Inside main()");

        Cups.cup1.f(99);
    }

}
class Cup{
    Cup(int marker){
        System.out.println("Cup("+marker+")");
    }
    void f(int marker){
        System.out.println("f("+marker+")");
    }
}
class Cups{
    static Cup cup = new Cup(0);
    static Cup cup1;
    static Cup cup2;
    static {
        cup1 = new Cup(1);
        cup2 = new Cup(2);
        System.out.println("在静态块中的执行");
    }
    static {
        Cup cup3 = new Cup(3);
        Cup cup4 = new Cup(4);
    }
    {
        System.out.println("在动态块中的执行");
    }
    {
        System.out.println("在动态快中的第二个执行");
    }
    Cups(){
        System.out.println("Cups");
    }
}

Cup(0)
Cup(1)
Cup(2)
在静态块中的执行
Cup(3)
Cup(4)
在动态块中的执行
在动态快中的第二个执行
Cups
Inside main()
f(99)

三、

数组的初始化:
int[] a = new int[number];
int[] a ={1,2,3};
int[] a = new int{1,2,3};
其实都知道,但是算是明白了后两种方法的好处,因为第一种只能用于数组定义处,后两种可以作为方法参数使用。
对象数组创建并不会和基本类型一样赋予初值,比如int[] a=new int[10];则a里面的值都是0。但是A[] a = new A[10];a里面的十个成员是为null而不是自动创建十个对象(就算是包装类也一样)。
代码如下

public class InitialValues{
    static String  a = "adfadf";
    static String b;

    public static void main(String[] args) {

        Other.main(new String[]{"a","b","c"});
    }

}
class Other{
    public static void main(String[] args) {
        for (String s:args){
            System.out.println(s);
        }
    }
}

四、

emmm,感觉算是面向对象的数组方面的应用,可变参数列表:
首先,如果以Object作为数组类型,其实一个数组里面是可以放任意类型的数据,因为Object是所有对象的父类。所以JavaSE5里面开始加入可变参数列表特性,具体表现如下

public class InitialValues{
    public static void main(String[] args) {
        printArray(1,new Float(2.1),new Double(11.11));
        printArray("aa","bb","cc");
        printArray(new A(),new A(),new A());
        printArray();
    }
    static void printArray(Object... args){
        for (Object o:args){
            System.out.print(o+" ");
        }
        System.out.println();
    }
}
class A{}

这里可以不用显式的使用数组作为参数,该特性可以使方法参数直接注入,而不用声明为Object数组且支持empty的输入,但是这个特性使重载变得复杂,因为可变参数支持无参的输入,如果有多个可变参数的同名方法,则调用无参方法时无法知道到底调用哪个,可以给所有拥有可变参数的同名方法添加一个非可变参数。PSVM里面的String[] args可以替换为可变参数。
如果没有这个特性,则代码形式如下:

public class InitialValues{
    public static void main(String[] args) {
        printArray(new Object[]{1,new Float(2.1),new Double(11.11) });
        printArray(new Object[]{"aa","bb","cc"});
        printArray(new Object[]{new A,new A(),new A()});
        printArray();
    }
    static void printArray(Object[] args){
        for (Object o:args){
            System.out.print(o+"");
        }
        System.out.println();
    }
}
class A{}

五、

本来书上还有介绍ENUM,但是第五章真的只有些API,暂且略过。

六、

重载:就是两个函数名相同时的区分,可以用参数的类型不同,甚至是参数传入顺序不同来区分,注意不能用返回类型不同来区分。