转载声明:文章来源https://blog.csdn.net/yangyan19870319/article/details/6202403
相信好多人对java初始化问题一直存有疑惑,下面是我看到的比较详细的java初始化问题讲解
一 java初始化基础知识
1、 一个类的所有基本类型数据成员都会保证获得一个初始值。
非基本类型,会初始化为null
public class Initialization {  
int a;  
char b;  
short s;  
float f;  
long lo;  
double dou;  
byte e;  
boolean flag;  
       Object obj;  
  
public static void main(String [] args){  
    Initialization init = new Initialization();  
    init.print();  
}  
  
public void print(){  
    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);  
}出来结果为
int a=0  
char b=  
short s=0  
float f=0.0  
long lo=0  
double dou=0.0  
byte e=0  
boolean flag=false  
Object obj=null可见,java会为类的基本类型的变量提供一个初始值,各类型初始值不同,非基本类型初始为null。注意,这里的变量必须是类变量,注意,只会为类变量提供初始化,而局部变量不会。如果局部变量没有初始化,会收到一个出错信息
2、可以通过构造方法或其他方法进行初始化,但是不会妨碍java默认的初始化
看下面的例子
int i;  
       Object obj;  
public Initialization(){  
    System.out.println("before i="+i+"  obj="+obj);  
    i = 1;  
    obj = new Object();  
    System.out.println("after i="+i+" obj="+obj);  
}  
  
public static void main(String [] args){  
    Initialization init = new Initialization();  
}输出结果为
before i=0  obj=null  
after i=1 obj=java.lang.Object@de6ced由此可见,不论是基本类型,还是其他的类。java默认的初始化是最先发生的,位于一切方法之前。
3、static 数据的初始化
static 数据会发生上述同样的事情(基本类型,获得对应基本类型的初始化值;非基本类型,初始化为null) 
但是,由于static值只有一个存储区域,所以static值只会被初始化一次,看下面的例子
public static void main(String [] args){  
Cupboard cup = new Cupboard();  
cup = new Cupboard();  
    }  
     
    public class Cupboard {  
static Bowl bowl = new Bowl();  
  
public Cupboard(){  
    System.out.println("initialization Cupboard");  
}  
    }  
    public class Bowl {  
public Bowl(){  
    System.out.println("init ing Bowl~");  
}  
    }输出结果如下
init ing Bowl~  
initialization Cupboard  
initialization Cupboard所以说,static数据只会在第一次进行初始化,之后就不会了。
4、初始化顺序
在一个类中,无论变量的定义是在方法之前还是方法之后,都会在方法之前进行初始化的; 另外,static数据初始化位于非static数据初始化之前 
来看下边的例子
public static void main(String [] args){  
Cupboard cup = new Cupboard();  
  
  }  
  public class Cupboard {  
Pan pan = new Pan();  
public Cupboard(){  
    System.out.println("initialization Cupboard");  
}  
static Bowl bowl = new Bowl();  
  }  
  public class Bowl {  
public Bowl(){  
    System.out.println("init ing Bowl~");  
}  
  }  
  public class Pan {  
public Pan(){  
    System.out.println("initialization Pan");  
}  
  }结果如下
init ing Bowl~  
initialization Pan  
initialization Cupboard5、静态块
静态块里的变量初始化顺序位于普通变量之前,和static变量相比,则是完全由定义的顺序来决定了。另外,静态块里的变量也是只初始化一次,这点和static变量一致。示例如下
public class Other {  
static{  
    Bowl bowl2 = new Bowl(2);  
}  
static Bowl bowl = new Bowl(1);  
  
private Bowl bowl3 = new Bowl(3);  
  
public static void main(String [] args){  
    Other other = new Other();  
    other = new Other();  
}  
    }  
    public class Bowl {  
public Bowl(){  
    System.out.println("init ing Bowl~");  
}  
  
public Bowl(int i){  
    System.out.println("init ing Bowl"+i);  
}  
    }输出结果为
init ing Bowl2  
init ing Bowl1  
init ing Bowl3  
init ing Bowl3如果调换static变量和静态块的位置,输出结果如下
init ing Bowl1  
init ing Bowl2  
init ing Bowl3  
init ing Bowl36、涉及到继承时 初始化顺序
初始化时,如果有static变量或静态块,其初始化顺序是位于最前面的,无论变量位于子类还是父类中,它们二者之间的顺序,可参见第5点; static变量初始完了后,先初始化父类,然后是子类。 
示例如下 
public class Base {  
Bowl bowl = new Bowl(1);  
public Base(){  
    System.out.println("initialization Class Base");  
}  
static Bowl bowl5 = new Bowl(5);  
static{  
    Bowl bowl6 = new Bowl(6);  
}  
    }  
    public class Sub extends Base {  
Bowl bow2 = new Bowl(2);  
public Sub(){  
    System.out.println("initialize Sub");  
}  
static Bowl bowl3 = new Bowl(3);  
  
static{  
    Bowl bowl4 = new Bowl(4);  
}  
    }  
    public class Test {  
public static void main(String []args){  
    Sub sub = new Sub();  
}  
    }输出结果如下
init ing Bowl5  
init ing Bowl6  
init ing Bowl3  
init ing Bowl4  
init ing Bowl1  
initialization Class Base  
init ing Bowl2  
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
package cn.edu.xupt.test;  
  
//: initialization/StaticInitialization.java  
//Specifying initial values in a class definition.  
  
//无论创建多少对象, 静态数据都只占用一份存储区域  
//初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化), 而后是"非静态"对象  
//载入.class文件(这将创建Class对象),有关静态初始化的所有动作执行.  
//静态初始化只在Class对象首次加载的时候进行一次  
class Bowl {  
    Bowl(int marker) {  
        System.out.println("Bowl(" + marker + ")");  
    }  
  
    void f1(int marker) {  
        System.out.println("f1(" + marker + ")");  
    }  
}  
  
class Table {  
    static Bowl bowl1 = new Bowl(1);  
  
    Table() {  
        System.out.println("Table()");  
        bowl2.f1(1);  
    }  
  
    void f2(int marker) {  
        System.out.println("f2(" + marker + ")");  
    }  
  
    static Bowl bowl2 = new Bowl(2);  
}  
  
class Cupboard {  
    Bowl bowl3 = new Bowl(3);  
    static Bowl bowl4 = new Bowl(4);  
  
    Cupboard() {  
        System.out.println("Cupboard()");  
        bowl4.f1(2);  
    }  
  
    void f3(int marker) {  
        System.out.println("f3(" + marker + ")");  
    }  
  
    static Bowl bowl5 = new Bowl(5);  
}  
  
public class StaticInitialization {  
    public static void main(String[] args) {  
        System.out.println("Creating new Cupboard() in main");  
        new Cupboard();  
        System.out.println("Creating new Cupboard() in main");  
        new Cupboard();  
        table.f2(1);  
        cupboard.f3(1);  
    }  
  
    static Table table = new Table();  
    static Cupboard cupboard = new Cupboard();  
} /* 
 * Output:  
 * Bowl(1) 
Bowl(2) 
Table() 
f1(1) 
Bowl(4) 
Bowl(5) 
Bowl(3) 
Cupboard() 
f1(2) 
Creating new Cupboard() in main 
Bowl(3) 
Cupboard() 
f1(2) 
Creating new Cupboard() in main 
Bowl(3) 
Cupboard() 
f1(2) 
f2(1) 
f3(1) 
 */// :~
                
                
                    
                            
                            
                                    
                                    
帖子还没人回复快来抢沙发