詳解Java中類的加載與其初始化
java內(nèi)存分析

類加載的過(guò)程

類的加載與ClassLoader的理解

類的初始化
package Collections;
public class text1 {
public static void main(String[]args){
A a=new A();
System.out.println(A.m);
}
}
class A{
static {
System.out.println("A類靜態(tài)代碼塊初始化");
m=300;
}
static int m=100;
public A(){
System.out.println("A類的無(wú)參構(gòu)造初始化");
}
}輸出:
A類靜態(tài)代碼塊初始化
A類的無(wú)參構(gòu)造初始化
100
為什么最終輸出的m值為100呢?
分析如下:
首先類進(jìn)行加載和鏈接,如下所示:

注:在鏈接階段的準(zhǔn)備工作時(shí),編譯器會(huì)為類變量賦默認(rèn)值為0,即此時(shí)的m為0
鏈接完畢后進(jìn)行類的初始化,這一過(guò)程將會(huì)執(zhí)行類構(gòu)造器()方法,將類中所有類變量的賦值語(yǔ)句以及靜態(tài)代碼塊中的語(yǔ)句收集和合并:
<clinit>() {
System.out.println("A類靜態(tài)代碼塊初始化");
m=300;
m=100;
}
第二條m的賦值語(yǔ)句,覆蓋了第一條的300,因此最終輸出為100
會(huì)發(fā)生類的初始化的場(chǎng)景
類的主動(dòng)引用(一定會(huì)發(fā)生類的初始化)

類的主動(dòng)引用
package Collections;
import static Collections.Son.m;
public class text1 {
static {
System.out.println("Main類被加載");
}
public static void main(String[]args) throws ClassNotFoundException {
Son son=new Son();
}
}
class Father{
static int a=10;
static{
System.out.println("Father類被加載");
}
}
class Son extends Father{
static {
System.out.println("子類被加載");
m= 300;
}
static int m =100;
static final int M = 1;
}輸出:
Main類被加載
Father類被加載
子類被加載
反射也會(huì)產(chǎn)生主動(dòng)引用
package Collections;
import static Collections.Son.m;
???????public class text1 {
static {
System.out.println("Main類被加載");
}
public static void main(String[]args) throws ClassNotFoundException {
Class.forName("Collections.Son");
}
}
class Father{
static int a=10;
static{
System.out.println("Father類被加載");
}
}
class Son extends Father{
static {
System.out.println("子類被加載");
m= 300;
}
static int m =100;
static final int M = 1;
}輸出:
Main類被加載
Father類被加載
子類被加載
類的被動(dòng)引用(不會(huì)發(fā)生類的初始化)
當(dāng)訪問(wèn)一個(gè)靜態(tài)域時(shí),只有真正聲明這個(gè)域的類才會(huì)被初始化,如:當(dāng)通過(guò)子類引用父類的靜態(tài)變量,不會(huì)導(dǎo)致子類初始化。
舉例:
package Collections;
import static Collections.Son.m;
???????public class text1 {
static {
System.out.println("Main類被加載");
}
public static void main(String[]args) throws ClassNotFoundException {
System.out.println(Son.a);
}
}
class Father{
static int a=10;
static{
System.out.println("Father類被加載");
}
}
class Son extends Father{
static {
System.out.println("子類被加載");
m= 300;
}
static int m =100;
static final int M = 1;
}輸出:
Main類被加載
Father類被加載
10
通過(guò)數(shù)組定義類引用,不會(huì)觸發(fā)此類的初始化
舉例:
package Collections;
import static Collections.Son.m;
???????public class text1 {
static {
System.out.println("Main類被加載");
}
public static void main(String[]args) throws ClassNotFoundException {
Son[] arry=new Son[5];
}
}
class Father{
static int a=10;
static{
System.out.println("Father類被加載");
}
}
class Son extends Father{
static {
System.out.println("子類被加載");
m= 300;
}
static int m =100;
static final int M = 1;
}輸出:
Main類被加載
引用常量不會(huì)觸發(fā)此類的初始化(常量在鏈接階段就存入調(diào)用類的常量池中了)
舉例:
package Collections;
import static Collections.Son.m;
???????public class text1 {
static {
System.out.println("Main類被加載");
}
public static void main(String[]args) throws ClassNotFoundException {
System.out.println(Son.M);
}
}
class Father{
static int a=10;
static{
System.out.println("Father類被加載");
}
}
class Son extends Father{
static {
System.out.println("子類被加載");
m= 300;
}
static int m =100;
static final int M = 1;
}輸出:
Main類被加載
???????1
以上就是詳解Java中類的加載與其初始化的詳細(xì)內(nèi)容,更多關(guān)于Java類加載與初始化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring?security?oauth2以redis作為tokenstore及jackson序列化失敗問(wèn)題
這篇文章主要介紹了Spring?security?oauth2以redis作為tokenstore及jackson序列化失敗問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教<BR>2024-04-04
SpringBoot系列教程JPA之基礎(chǔ)環(huán)境搭建的方法
這篇文章主要介紹了SpringBoot系列教程JPA之基礎(chǔ)環(huán)境搭建的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Java動(dòng)態(tài)線程池插件dynamic-tp集成zookeeper
ZooKeeper是一個(gè)分布式的,開(kāi)放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個(gè)開(kāi)源的實(shí)現(xiàn),是Hadoop和Hbase的重要組件。它是一個(gè)為分布式應(yīng)用提供一致性的軟件,提供的功能包括:配置維護(hù)、域名服務(wù)、分布式同步、組服務(wù)等2023-03-03
Springboot利用Redis實(shí)現(xiàn)接口冪等性攔截
這篇文章主要為大家介紹了Springboot如何利用Redis實(shí)現(xiàn)接口冪等性攔截。本文將通過(guò)自定義注解+redis+攔截器+MD5?實(shí)現(xiàn),感興趣的可以了解一下2022-06-06
詳解Java如何通過(guò)Socket實(shí)現(xiàn)查詢IP
在本文中,我們來(lái)學(xué)習(xí)下如何找到連接到服務(wù)器的客戶端計(jì)算機(jī)的IP地址。我們將創(chuàng)建一個(gè)簡(jiǎn)單的客戶端-服務(wù)器場(chǎng)景,讓我們探索用于TCP/IP通信的java.net?API,感興趣的可以了解一下2022-10-10
SpringBoot中@RestControllerAdvice注解實(shí)現(xiàn)全局異常處理類
這篇文章主要介紹了SpringBoot中@RestControllerAdvice注解全局異常處理類,springboot中使用@RestControllerAdvice注解,完成優(yōu)雅的全局異常處理類,可以針對(duì)所有異常類型先進(jìn)行通用處理后再對(duì)特定異常類型進(jìn)行不同的處理操作,需要的朋友可以參考下2024-01-01

