10-JAVA初始化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10-JAVA初始化相关的知识,希望对你有一定的参考价值。

Java初始化的顺序如下:

父类静态初始化---->子类静态初始化---->父类初始化块---->父类构造方法---->子类初始化块---->子类构造方法。

 

1 概述

Java中,每个类在使用前都需要进行初始化,所以理解初始化是理解java的开端。

在Java中有两个隐藏了的方法:<clinit></clinit>和<init></init>。这两个方法是属于Java虚拟机的,也就是说在程序中我们是不可以调用的。具体可见:

http://dev2dev.bea.com.cn/bbsdoc/20060704286.html

<clinit></clinit><clinit></clinit><clint></clint>"clint<clint></clint>":对类进行初始化。即在类被装载时,JVM会调用内置的<clinit></clinit>方法对类成员和静态初始化块进行初始化调用(也就是static部分)。

<init></init><init></init>"init<init></init>":对对象进行初始化。即在创建对象时,JVM会调用<init></init>方法对实例变量和初始化块进行初始化(然后才是构造方法)。

2 举例说明

2.1 普通类初始化

 

 输出:

<st1:city w:st="on"><st1:place w:st="on"> Normal</st1:place></st1:city> <init></init>

 Normal construct<o:p> </o:p>

 结论:对象初始化时,先是初始化块,然后才是构造方法。   

2.2 普通类静态初始化 

 

输出:

NormalStatic <static init=""></static>

NormalStatic <init></init>

NormalStatic construct<o:p> </o:p>

结论:先是初始化静态部分,然后才初始化其他部分(类是先加载,然后才创建对象,而静态部分是在类加载时初始化的)。

 

 

2.3 继承于普通类的初始化

 

输出:

 Special <init></init>

 Special construct

<st1:place w:st="on"><st1:city w:st="on"> Normal</st1:city></st1:place> <init></init>

 Normal construct<o:p> </o:p>

 结论:先初始化父类(默认调用父类的无参构造方法),然后才初始化子类。

 

 

2.4 继承于有静态初始化的类的初始化 

 

输出:

SpecialStatic <static init=""></static>

NormalStatic <static init=""></static>

SpecialStatic <init></init>

SpecialStatic construct

NormalStatic <init></init>

NormalStatic construct<o:p> </o:p>

结论:先静后动,先父后子。 

  

3 总结 

Java初始化的顺序如下:

父类静态初始化---->子类静态初始化---->父类初始化块---->父类构造方法---->子类初始化块---->子类构造方法。

 

 

 

一  java初始化基础知识
1、 一个类的所有基本类型数据成员都会保证获得一个初始值。 
非基本类型,会初始化为null 

 

Java代码 
  1.   public class Initialization {  
  2. int a;  
  3. char b;  
  4. short s;  
  5. float f;  
  6. long lo;  
  7. double dou;  
  8. byte e;  
  9. boolean flag;  
  10.        Object obj;  
  11.   
  12. public static void main(String [] args){  
  13.     Initialization init = new Initialization();  
  14.     init.print();  
  15. }  
  16.   
  17. public void print(){  
  18.     System.out.println("int a="+a+"/nchar b="+b+" /n"+" short s="+s+"/n float f="+f+"/n long lo="+lo+"/n double dou="+dou+"/n byte e="+e+"/n boolean flag="+flag+"/n Object obj="+obj);  
  19. }  

 


出来结果为 

 

Java代码 
  1. int a=0  
  2. char b=  
  3. short s=0  
  4. float f=0.0  
  5. long lo=0  
  6. double dou=0.0  
  7. byte e=0  
  8. boolean flag=false  
  9. Object obj=null  

 


可见,java会为类的基本类型的变量提供一个初始值,各类型初始值不同,非基本类型初始为null。注意,这里的变量必须是类变量,注意,只会为类变量提供初始化,而局部变量不会。如果局部变量没有初始化,会收到一个出错信息 

 

 

 


2、可以通过构造方法或其他方法进行初始化,但是不会妨碍java默认的初始化

 

  看下面的例子 

 

Java代码 
  1.        int i;  
  2.        Object obj;  
  3. public Initialization(){  
  4.     System.out.println("before i="+i+"  obj="+obj);  
  5.     i = 1;  
  6.     obj = new Object();  
  7.     System.out.println("after i="+i+" obj="+obj);  
  8. }  
  9.   
  10. public static void main(String [] args){  
  11.     Initialization init = new Initialization();  
  12. }  
  13.    

 


  输出结果为 

 

Java代码 
  1. before i=0  obj=null  
  2. after i=1 obj=java.lang.Object@de6ced  

 


由此可见,不论是基本类型,还是其他的类。java默认的初始化是最先发生的,位于一切方法之前。 
3、static 数据的初始化 
  static 数据会发生上述同样的事情(基本类型,获得对应基本类型的初始化值;非基本类型,初始化为null) 
  但是,由于static值只有一个存储区域,所以static值只会被初始化一次,看下面的例子 

 

Java代码 
  1.     public static void main(String [] args){  
  2. Cupboard cup = new Cupboard();  
  3. cup = new Cupboard();  
  4.     }  
  5.      
  6.     public class Cupboard {  
  7. static Bowl bowl = new Bowl();  
  8.   
  9. public Cupboard(){  
  10.     System.out.println("initialization Cupboard");  
  11. }  
  12.     }  
  13.     public class Bowl {  
  14. public Bowl(){  
  15.     System.out.println("init ing Bowl~");  
  16. }  
  17.     }  
  18.    

 


  输出结果如下 

 

Java代码 
  1. init ing Bowl~  
  2. initialization Cupboard  
  3. initialization Cupboard  

 


所以说,static数据只会在第一次进行初始化,之后就不会了。 

4、初始化顺序 
  在一个类中,无论变量的定义是在方法之前还是方法之后,都会在方法之前进行初始化的; 
  另外,static数据初始化位于非static数据初始化之前 
来看下边的例子 

 

Java代码 
  1.   public static void main(String [] args){  
  2. Cupboard cup = new Cupboard();  
  3.   
  4.   }  
  5.   public class Cupboard {  
  6. Pan pan = new Pan();  
  7. public Cupboard(){  
  8.     System.out.println("initialization Cupboard");  
  9. }  
  10. static Bowl bowl = new Bowl();  
  11.   }  
  12.   public class Bowl {  
  13. public Bowl(){  
  14.     System.out.println("init ing Bowl~");  
  15. }  
  16.   }  
  17.   public class Pan {  
  18. public Pan(){  
  19.     System.out.println("initialization Pan");  
  20. }  
  21.   }  
  22.    

 


结果如下 

 

Java代码 
  1.     init ing Bowl~  
  2. initialization Pan  
  3. initialization Cupboard  
  4.    

 



5、静态块 
  静态块里的变量初始化顺序位于普通变量之前,和static变量相比,则是完全由定义的顺序来决定了。另外,静态块里的变量也是只初始化一次,这点和static变量一致。示例如下 

 

Java代码 
  1.    public class Other {  
  2. static{  
  3.     Bowl bowl2 = new Bowl(2);  
  4. }  
  5. static Bowl bowl = new Bowl(1);  
  6.   
  7. private Bowl bowl3 = new Bowl(3);  
  8.   
  9. public static void main(String [] args){  
  10.     Other other = new Other();  
  11.     other = new Other();  
  12. }  
  13.     }  
  14.     public class Bowl {  
  15. public Bowl(){  
  16.     System.out.println("init ing Bowl~");  
  17. }  
  18.   
  19. public Bowl(int i){  
  20.     System.out.println("init ing Bowl"+i);  
  21. }  
  22.     }  
  23.    

 


输出结果为 

  

Java代码 
  1. init ing Bowl2  
  2. init ing Bowl1  
  3. init ing Bowl3  
  4. init ing Bowl3  

 


如果调换static变量和静态块的位置,输出结果如下 

 

Java代码 
  1. init ing Bowl1  
  2. init ing Bowl2  
  3. init ing Bowl3  
  4. init ing Bowl3  

 


6、涉及到继承时 初始化顺序 
  初始化时,如果有static变量或静态块,其初始化顺序是位于最前面的,无论变量位于子类还是父类中,它们二者之间的顺序,可参见第5点; 
  static变量初始完了后,先初始化父类,然后是子类。 
  示例如下 

 

Java代码 
  1.     public class Base {  
  2. Bowl bowl = new Bowl(1);  
  3. public Base(){  
  4.     System.out.println("initialization Class Base");  
  5. }  
  6. static Bowl bowl5 = new Bowl(5);  
  7. static{  
  8.     Bowl bowl6 = new Bowl(6);  
  9. }  
  10.     }  
  11.     public class Sub extends Base {  
  12. Bowl bow2 = new Bowl(2);  
  13. public Sub(){  
  14.     System.out.println("initialize Sub");  
  15. }  
  16. static Bowl bowl3 = new Bowl(3);  
  17.   
  18. static{  
  19.     Bowl bowl4 = new Bowl(4);  
  20. }  
  21.     }  
  22.     public class Test {  
  23. public static void main(String []args){  
  24.     Sub sub = new Sub();  
  25. }  
  26.     }  
  27.    

 


输出结果如下 

 

Java代码 
  1. init ing Bowl5  
  2. init ing Bowl6  
  3. init ing Bowl3  
  4. init ing Bowl4  
  5. init ing Bowl1  
  6. initialization Class Base  
  7. init ing Bowl2  
  8. initialize Sub  

 

二 问题举例

 

 

 

package test;

class Singleton { 

private static Singleton obj = new Singleton();  

public static int counter1; 

public static int counter2 = 0; 

private Singleton() {    

counter1++;   

counter2++;    

}   

public static Singleton getInstance() { 

return obj;  

}    

public class MyMain {  

public static void main(String[] args) { 

Singleton obj = Singleton.getInstance();  

System.out.println("obj.counter1=="+obj.counter1);  

System.out.println("obj.counter2=="+obj.counter2);  

}  

这段程序代码输出,实际运行结果:

obj.counter1==1

obj.counter2==0

相信大家跟我一样会对这个结果存有疑问,这段代码中尤其注意:private static Singleton obj = new Singleton();   在类Singleton中的位置,改变位置会有不同结果。关于这段代码运行结果的解释:

当程序执行private static Singleton obj = new Singleton(); 句的时候就去调用了Singleton构造器,此时counter1、counter2都是1,但是接着执行向下执行:public static int counter1;时将1赋给counter1,执行public static int counter2 = 0;时重新给counter2赋值为0

 

三  典型初始化例子

Java初始话很好的一个例子, 摘自Think in Java

Java代码 
    1. package cn.edu.xupt.test;  
    2.   
    3. //: initialization/StaticInitialization.java  
    4. //Specifying initial values in a class definition.  
    5.   
    6. //无论创建多少对象, 静态数据都只占用一份存储区域  
    7. //初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化), 而后是"非静态"对象  
    8. //载入.class文件(这将创建Class对象),有关静态初始化的所有动作执行.  
    9. //静态初始化只在Class对象首次加载的时候进行一次  
    10. class Bowl {  
    11.     Bowl(int marker) {  
    12.         System.out.println("Bowl(" + marker + ")");  
    13.     }  
    14.   
    15.     void f1(int marker) {  
    16.         System.out.println("f1(" + marker + ")");  
    17.     }  
    18. }  
    19.   
    20. class Table {  
    21.     static Bowl bowl1 = new Bowl(1);  
    22.   
    23.     Table() {  
    24.         System.out.println("Table()");  
    25.         bowl2.f1(1);  
    26.     }  
    27.   
    28.     void f2(int marker) {  
    29.         System.out.println("f2(" + marker + ")");  
    30.     }  
    31.   
    32.     static Bowl bowl2 = new Bowl(2);  
    33. }  
    34.   
    35. class Cupboard {  
    36.     Bowl bowl3 = new Bowl(3);  
    37.     static Bowl bowl4 = new Bowl(4);  
    38.   
    39.     Cupboard() {  
    40.         System.out.println("Cupboard()");  
    41.         bowl4.f1(2);  
    42.     }  
    43.   
    44.     void f3(int marker) {  
    45.         System.out.println("f3(" + marker + ")");  
    46.     }  
    47.   
    48.     static Bowl bowl5 = new Bowl(5);  
    49. }  
    50.   
    51. public class StaticInitialization {  
    52.     public static void main(String[] args) {  
    53.         System.out.println("Creating new Cupboard() in main");  
    54.         new Cupboard();  
    55.         System.out.println("Creating new Cupboard() in main");  
    56.         new Cupboard();  
    57.         table.f2(1);  
    58.         cupboard.f3(1);  
    59.     }  
    60.   
    61.     static Table table = new Table();  
    62.     static Cupboard cupboard = new Cupboard();  
    63. /* 
    64.  * Output:  
    65.  * Bowl(1) 
    66. Bowl(2) 
    67. Table() 
    68. f1(1) 
    69. Bowl(4) 
    70. Bowl(5) 
    71. Bowl(3) 
    72. Cupboard() 
    73. f1(2) 
    74. Creating new Cupboard() in main 
    75. Bowl(3) 
    76. Cupboard() 
    77. f1(2) 
    78. Creating new Cupboard() in main 
    79. Bowl(3) 
    80. Cupboard() 
    81. f1(2) 
    82. f2(1) 
    83. f3(1) 
    84.  */// :~ 

 

 






























以上是关于10-JAVA初始化的主要内容,如果未能解决你的问题,请参考以下文章

Java知识点总结

java初始化中静态方法得初始化吗?何时初始化? 一般方法得初始化吗?何时初始化?

直接初始化&拷贝初始化&值初始化

Java的初始化块

Kotlin类的初始化 ④ ( lateinit 延迟初始化 | ::属性名称.isInitialized 检查属性是否初始化 | lazy 惰性初始化 )

Kotlin类的初始化 ④ ( lateinit 延迟初始化 | ::属性名称.isInitialized 检查属性是否初始化 | lazy 惰性初始化 )