相信好多人對Java初始化問題一直存有疑惑,下面是我看到的比較詳細的java初始化問題講解
一 java初始化基礎知識 1、 一個類的所有基本類型數(shù)據(jù)成員都會保證獲得一個初始值。 非基本類型,會初始化為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默認的初始化是最先發(fā)生的,位于一切方法之前。 3、static 數(shù)據(jù)的初始化 static 數(shù)據(jù)會發(fā)生上述同樣的事情(基本類型,獲得對應基本類型的初始化值;非基本類型,初始化為null) 但是,由于static值只有一個存儲區(qū)域,所以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數(shù)據(jù)只會在第一次進行初始化,之后就不會了。
4、初始化順序 在一個類中,無論變量的定義是在方法之前還是方法之后,都會在方法之前進行初始化的; 另外,static數(shù)據(jù)初始化位于非static數(shù)據(jù)初始化之前 來看下邊的例子
- 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 Cupboard
-
5、靜態(tài)塊 靜態(tài)塊里的變量初始化順序位于普通變量之前,和static變量相比,則是完全由定義的順序來決定了。另外,靜態(tài)塊里的變量也是只初始化一次,這點和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變量和靜態(tài)塊的位置,輸出結果如下
- init ing Bowl1
- init ing Bowl2
- init ing Bowl3
- init ing Bowl3
6、涉及到繼承時 初始化順序 初始化時,如果有static變量或靜態(tài)塊,其初始化順序是位于最前面的,無論變量位于子類還是父類中,它們二者之間的順序,可參見第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中的位置,改變位置會有不同結果。關于這段代碼運行結果的解釋:
當程序執(zhí)行private static Singleton obj = new Singleton(); 句的時候就去調用了Singleton構造器,此時counter1、counter2都是1,但是接著執(zhí)行向下執(zhí)行:public static int counter1;時將1賦給counter1,執(zhí)行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.
-
- //無論創(chuàng)建多少對象, 靜態(tài)數(shù)據(jù)都只占用一份存儲區(qū)域
- //初始化的順序是先靜態(tài)對象(如果它們尚未因前面的對象創(chuàng)建過程而被初始化), 而后是"非靜態(tài)"對象
- //載入.class文件(這將創(chuàng)建Class對象),有關靜態(tài)初始化的所有動作執(zhí)行.
- //靜態(tài)初始化只在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)
- */// :~
|