Java初始化小结

2016-03-27  本文已影响28人  KokutouDa

写的是一些看了《Java编程思想》4th和网上查的一些资料的总结,有错误的地方欢迎指正。

静态数据初始化

不管创建了多少对象都只占用单个存储区域。
static不能应用于局部变量,只能作用于域。
初始化完静态数据后再初始化非静态的。
静态数据会在加载类时初始化,成员变量则会在创建类的对象时才初始化。

class SimpleClass {

    {
        i = 3;
    }

    static int i;
}

    public void localVariable() {
//        static int  b = 3;              //局部变量里不允许使用static
    }

class Test {
    public static void main(String[] args) {
//        SimpleClass sc = new SimpleClass();   
        System.out.println(SimpleClass.i);
    }
}  /*output
    0
    */

当创建对象时,输出的结果是3,当注释掉时,输出的是0。

成员变量

变量在局部变量里未赋值时,会报错。
变量可以通过方法来赋值。

class Test1 {
    private int j;
    private int i = getI();           //通过方法给变量赋值

    public void localVarible() {
        int k;
        System.out.println(k);     //error:变量'k'可能没有初始化
        System.out.println(j);
    }

    public int getI() {
        i = 10;
        return i;
    }
}

当把 System.out.println(k) 注释掉时编译成功。

用构造器初始化

构造器名称和类名相同。
构造器是特殊的方法,它没有返回值。
java在操作对象前会分配空间,会调用相应的构造器,保证初始化。

默认构造器(不含参数)

导出类创建对象时会隐式的调用超类的默认构造器。如果不调用超类构造器,则当导出类调用超类的变量或方法时会出现还没有初始化的情况。 参考:
http://zhidao.baidu.com/link?url=Ex3zcGjxl5_XPHnyFBynsUKeBWPGB1j6d6zgLfEOZw4wT-geMILWiCaWPU6yPH4uf3kKwR4mxsUxb7G7ph6W8bDDjRU1UsL8GN74QVMiucq

class Super {
    Super() {
        System.out.println("Super()");
    }
}

class Derived extends Super {
    Derived() {
        System.out.println("Derive()");
    }
}

class Main {
    public static void main(String[] args) {
        Derived d = new Derived();       //会先调用超类的构造器
    }
}/*output
Super()
Derived() */
含参构造器

构造器也可以带参数, 当只有一种构造器时,将不会其他任何的形式来创建对象 。
当超类中只有含参的构造器时,导出类初始化时必须先用super调用超类构造器。

class Super {
    Super(String str) {
        System.out.println("Super(str)");
    }
}

class Derived extends Super {
    Derived() {
        super("str");
        System.out.println("Derived()");
    }
    Derived(String str) { 
        super("str");
        System.out.println("Derived(str)");
    }
}

为了保证导出类的成员和方法正确的初始化,当注释掉 super("str")时会报错。

数组初始化

数组之间赋值传递的是引用。

class ArrayInitialization { 

    public static void main(String[] args) { 
        int[] i = {1, 2, 3, 4, 5, 6}; 
        int[] j = i; 

        for (int n = 0; n < i.length; n++) 
            i[n] = i[n] + 1; 

        for (int n : j) 
            System.out.println(n);
    } 
}  /**output 
  2
  3 
  4 
  5 
  6 
  7  * / 

继承初始化

class Super { 
    static { 
        System.out.println("超类静态初始化块");
    } 
    static int i = 5; 

    int j = 6;  
    { 
        System.out.println("超类普通初始化块"); 
    } 

    Super() { 
        System.out.println("Super()"); 
    } 
} 

class Derived extends Super { 
    static int k = 10; 
    static { 
        System.out.println("导出类静态初始化块"); 
    }   

    { 
        System.out.println("导出类普通初始化块"); 
    } 
    int h = 11; 

    Derived() { 
        System.out.println("Derived()"); 
    } 

    public static void main(String[] args) {
        Derived d = new Derived();
    }
}     /** output:
 超类静态初始化块
 导出类静态初始化块
 超类普通初始化块
 Super()
 导出类普通初始化块
 Derived() */

当没有继承关系且只创建Super对象时:

class Super {
    static {
        System.out.println("超类静态初始化块");
    }
    static int i = 5;

    int j = 6;
    {
        System.out.println("超类普通初始化块");
    }

    Super() {
        System.out.println("Super()");
    }
}

class Derived  {
    static int k = 10;
    static {
        System.out.println("导出类静态初始化块");
    }

    {
        System.out.println("导出类普通初始化块");
    }
    int h = 11;

    Derived() {
        System.out.println("Derived()");
    }

    public static void main(String[] args) {
        Super s = new Super();
    }
}  /*
导出类静态初始化块
超类静态初始化块
超类普通初始化块
Super()
*/

这时候会先初始化Derived类的静态数据,再始初化Super的静态数据。因为JVM虚拟机会先加载类的main方法,判断其有无超类,如果没有就直接初始化静态数据;如果有就先初始化基类的构造器。

初始化顺序:

在初始化之前会把所有成员都赋初始值(0,null等)。
超类静态代码块 >> i >> k >> 导出类静态代码块 >> j >>超类静态代码块 >> 超类构造器 >> 导出类静态代码块 >> h >> 导出类构造器 。

向上转型时

当导出类构造器重写了超类构造器调用的方法后,在创建了对象进行初始化时超类构造器会调用导出类覆写的方法,但变量不会被重写,可以当它隐式的用private修饰了。

class Super {
    public int i = 3;
    public int j = 4;
    public Super() {
        System.out.println("i = " + i + ", j = " + j);
        rewriteMethod();
    }

    public void rewriteMethod() {
        System.out.println("Super's method");
    }
}
class Derived extends Super {
    public int i = 5;
    public int j = 6;
    public Derived() {
        System.out.println("i = " + i + ", j = " + j);
        rewriteMethod();
    }

    @Override
    public void rewriteMethod() {
        System.out.println("Derived's method");
    }
}

class Main {
    public static void main(String[] args) {
        Super s = new Derived();
    }
}
    /*output:
    i = 3, j = 4
    Derived's method
    i = 5, j = 6
    Derived's method*/
上一篇下一篇

猜你喜欢

热点阅读