需要前置技能
- 接口
- 抽象類
- 實現(xiàn)
- 繼承
類的生命周期
- 加載
- 連接 (連接又分為 驗證、準(zhǔn)備、解析)
- 初始化
- 使用
- 卸載
說說準(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)值:
- 基本類型(int、long、short、char、byte、boolean、float、double)的默認(rèn)值為0。
- 引用類型的默認(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