日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java中ClassLoader浅析.

發布時間:2025/3/21 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中ClassLoader浅析. 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、問題

請在Eclipse中新建如下類,并運行它:

1 package java.lang; 2 3 public class Long { 4 public static void main(String[] args) { 5 System.out.println("Hi, i am here"); 6 } 7 }

你能猜到它的運行如果嗎? 不錯,就是如下這個樣子!

錯誤: 在類 java.lang.Long 中找不到 main 方法, 請將 main 方法定義為:
public static void main(String[] args)
否則 JavaFX 應用程序類必須擴展javafx.application.Application

?





為什么呢,明明我在Long方法類中定義了main方法,為什么說main方法沒有定義呢?

本文將解決以上問題出現的原因。

二、ClassLoader的作用

我們都知道java程序寫好以后是以.java(文本文件)的文件存在磁盤上,然后,我們通過(bin/javac.exe)編譯命令把.java文件編譯成.class文件(字節碼文件),并存在磁盤上。但是程序要運行,首先一定要把.class文件加載到JVM內存中才能使用的,我們所講的classLoader,就是負責把磁盤上的.class文件加載到JVM內存中,如下圖所示:

你可以認為每一個Class對象擁有磁盤上的那個.class字節碼內容,每一個class對象都有一個getClassLoader()方法,得到是誰把我從.class文件加載到內存中變成Class對象的。

三、ClassLoader層次結構

請執行如下程序:

1 public class Test {2 public static void main(String[] args) {3 ClassLoader classLoader = Test.class.getClassLoader();4 System.out.println(classLoader);5 6 ClassLoader classLoader1 = classLoader.getParent();7 System.out.println(classLoader1);8 9 ClassLoader classLoader2 = classLoader1.getParent(); 10 System.out.println(classLoader2); 11 } 12 }

它的輸出是:

sun.misc.Launcher$AppClassLoader@2a139a55
sun.misc.Launcher$ExtClassLoader@7852e922
null

得到了 classLoader2就是null值了。這里其實有三個類加載器:

(1): 根類加載器(null)

它是由本地代碼(c/c++)實現的,你根本拿不到他的引用,但是他實際存在,并且加載一些重要的類,它加載(%JAVA_HOME%\jre\lib),如rt.jar(runtime)、i18n.jar等,這些是Java的核心類。

(2): 擴展類加載器(ExtClassLoader)

雖說能拿到,但是我們在實踐中很少用到它,它主要加載擴展目錄下的jar包, %JAVA_HOME%\lib\ext

(3): 應用類加載器(AppClassLoader)

它主要加載我們應用程序中的類,如Test,或者用到的第三方包,如jdbc驅動包等。

這里的父類加載器與類中繼承概念要區分,它們在class定義上是沒有父子關系的。

四、Class加載時調用類加載器的順序

當一個類要被加載時,有一個啟動類加載器和實際類加載器的概念,這個概念請看如下分析

如上面的Test.class要進行加載時,它將會啟動應用類加載器進行加載Test類,但是這個應用類加載器不會真正去加載他,而是會調用看是否有父加載器,結果有,是擴展類加載器,擴展類加載器也不會直接去加載,它看自己是否有父加載器沒,結果它還是有的,是根類加載器。

所以這個時候根類加載器就去加載這個類,可在%JAVA_HOME%\jre\lib下,它找不到com.wangmeng.Test這個類,所以他告訴他的子類加載器,我找不到,你去加載吧,子類擴展類加載器去%JAVA_HOME%\lib\ext去找,也找不著,它告訴它的子類加載器 AppClassLoader,我找不到這個類,你去加載吧,結果AppClassLoader找到了,就加到內存中,并生成Class對象。
這個時間時候啟動類加載器(應用類加載器)和實際類加載器(應用類加載器)是同一個.

這就是Java中著名的委托加載機制,看如下圖:

我們再來看一下 java.lang.Long的加載,按上面分析,應該是由根類加載器加載得到的,此時啟動類加載器是應用類加載器,但實際類加載器是根類加載器。

所以回到我們最開始那個問題,沒有main方法是因為執行的根本不是我們自己寫的類,執行的是java核心中的那個Long類,當然沒有main方法了。 這樣就防止我們應用中寫的類覆蓋掉java核心類。

轉載于:https://www.cnblogs.com/kexianting/p/8526998.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Java中ClassLoader浅析.的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。