美文网首页
Java初始化小结

Java初始化小结

作者: KokutouDa | 来源:发表于2016-03-27 18:59 被阅读28次

    写的是一些看了《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*/
    

    相关文章

      网友评论

          本文标题:Java初始化小结

          本文链接:https://www.haomeiwen.com/subject/vnallttx.html