淺談類的準(zhǔn)備和初始化

需要前置技能

  • 接口
  • 抽象類
  • 實現(xiàn)
  • 繼承

類的生命周期

  1. 加載
  2. 連接 (連接又分為 驗證、準(zhǔn)備、解析)
  3. 初始化
  4. 使用
  5. 卸載

說說準(zhǔn)備和初始化階段

準(zhǔn)備:
為靜態(tài)變量分配內(nèi)存和初始化默認(rèn)值

package com.lazymax.base.jvm.classload;
public class Prepare {
    static int a;
}
class Test{
    public static void main(String[] args) {
        System.out.println("result: " + Prepare.a);
    }
}
// 結(jié)果:  
result: 0

延伸出一個知識點:
默認(rèn)值:

  1. 基本類型(int、long、short、char、byte、boolean、float、double)的默認(rèn)值為0。
  2. 引用類型的默認(rèn)值為null。
package com.lazymax.base.jvm.classload;
public class Prepare {
    static final int a;
    static final Prepare prepare;
}
class Test{
    public static void main(String[] args) {
        System.out.println("result: " + Prepare.a);
        System.out.println("result: " + Prepare.prepare);
    }
}
// 結(jié)果:  
result: 0
result: null

初始化
主動引用(首次加載會導(dǎo)致初始化):

  • 通過new關(guān)鍵字實例化對象、讀取或設(shè)置類的靜態(tài)變量、調(diào)用類的靜態(tài)方法。
  • 通過反射方式執(zhí)行以上三種行為。
  • 初始化子類的時候,會觸發(fā)父類的初始化。
  • 作為程序入口直接運(yùn)行時(也就是直接調(diào)用main方法)
    其他情況叫做被動引用

特殊情況這種情況不會初始化類

package com.lazymax.base.jvm.classload;
public class Prepare {
    public static final String pools = "123";
}
class Test{
    public static void main(String[] args) {
        System.out.println(Prepare.pools);
    }
}
// 結(jié)果:  
123

為什么使用final?
final直接將數(shù)據(jù)放入使用類的常量池中,可以避免類的初始化、假如編譯后把Prepare.class 刪除打印結(jié)果依舊不變

父類也會初始化的情況

package com.lazymax.base.jvm.classload;
public class Prepare extends Parent{
    static String pools = "123";
}
class Parent{
    static {
        System.out.println("load");
    }
}
class Test{
    public static void main(String[] args) {
        System.out.println(Prepare.pools);
    }
}

父類不會初始化的情況

package com.lazymax.base.jvm.classload;
public class Prepare extends Parent{
    static final String pools = "123";
}
class Parent{
    static {
        System.out.println("load");
    }
}
class Test{
    public static void main(String[] args) {
        System.out.println(Prepare.pools);
    }
}

靜態(tài)參數(shù)初始化
順序為自上而下

package com.lazymax.base.jvm.classload;
public class Prepare{
    static {
        pools = "66";
    }
    static String pools = "123";
}
class Test{
    public static void main(String[] args) {
        System.out.println(Prepare.pools);
    }
}
// result:  
123

接口示例

package com.lazymax.base.jvm.classload;
public interface Prepare extends Parent{
    String pools = "123";
}
interface Parent{
    Demo demo = new Demo();
}
class Demo{
    static {
        System.out.println("load");
    }
}
class Test{
    public static void main(String[] args) {
        System.out.println(Prepare.pools);
    }
}
// result
123

總結(jié)
對final的常量直接引用不會導(dǎo)致類的初始化
非final靜態(tài)變量

package com.lazymax.base.jvm.classload;
public class Prepare {
    static final Demo pools = new Demo();
    static {
        System.out.println("load");
    }
}
class Demo{
    static {
        System.out.println("demo load");
    }
}
class Test{
    public static void main(String[] args) {
        System.out.println(Prepare.pools);
    }
}
// result  
demo load
load
com.lazymax.base.jvm.classload.Demo@3cb5cdba

感謝
深入理解JVM-張龍(bilibili)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容