java類加載之加載類的三種途徑

原文鏈接:https://blog.csdn.net/qq_30242987/article/details/88571383

1、由 new 關鍵字創建一個類的實例(靜態加載)
在由運行時刻用 new 方法載入
如:Dog dog = new Dog();

2、調用 Class.forName() 方法
通過反射加載類型,並創建對象實例
如:Class clazz = Class.forName(“Dog”);
Object dog =clazz.newInstance();

3、調用某個 ClassLoader 實例的 loadClass() 方法
通過該 ClassLoader 實例的 loadClass() 方法載入。應用程序可以通過繼承 ClassLoader 實現自己的類裝載器。
如:Class clazz = classLoader.loadClass(“Dog”);
Object dog =clazz.newInstance();

三者的區別:

1和2使用的類加載器是相同的,都是當前類加載器。(即:this.getClass.getClassLoader)。
3由用戶指定類加載器。如果需要在當前類路徑以外尋找類,則只能採用第3種方式。第3種方式加載的類與當前類分屬不同的命名空間。
另外:
1是靜態加載,2、3是動態加載

兩個異常(exception):

  • 靜態加載的時候如果在運行環境中找不到要初始化的類,拋出的是NoClassDefFoundError,它在JAVA的異常體系中是一個Error

  • 動態態加載的時候如果在運行環境中找不到要初始化的類,拋出的是ClassNotFoundException,它在JAVA的異常體系中是一個checked異常

Class.forName與ClassLoader.loadClass區別

Class的裝載包括3個步驟:加載(loading),連接(link),初始化(initialize).
Class.forName(className)實際上是調用Class.forName(className, true, this.getClass().getClassLoader())。第二個參數,是指Class被loading後是不是必須被初始化。
ClassLoader.loadClass(className)實際上調用的是ClassLoader.loadClass(name, false),第二個參數指Class是否被link。
Class.forName(className)裝載的class已經被初始化,而ClassLoader.loadClass(className)裝載的class還沒有被link。一般情況下,這兩個方法效果一樣,都能裝載Class。但如果程序依賴於Class是否被初始化,就必須用Class.forName(name)了。
例如,在JDBC編程中,常看到這樣的用法,Class.forName(“com.mysql.jdbc.Driver”).
如果換成了getClass().getClassLoader().loadClass(“com.mysql.jdbc.Driver”),就不行。
com.mysql.jdbc.Driver的源代碼如下:
// Register ourselves with the DriverManager
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException(“Can’t register driver!”);
}
}
原來,Driver在static塊中會註冊自己到java.sql.DriverManager。而static塊就是在Class的初始化中被執行。
所以這個地方就只能用Class.forName(className)。

對於相同的類,JVM最多會載入一次。但如果同一個class文件被不同的ClassLoader載入,那麼載入後的兩個類是完全不同的。因爲已被加載的類由該類的類加載器實例與該類的全路徑名的組合標識。設有 packagename.A Class ,分別被類加載器 CL1 和 CL2 加載,所以系統中有兩個不同的 java.lang.Class 實例: <CL1, packagename.A> 和 <CL2, packagename.A>。

classload過程
https://www.cnblogs.com/gdpuzxs/p/7044963.html
https://blog.csdn.net/javazejian/article/details/73413292#編寫自己的類加載器
jar包導入項目,啓動後classnotfound:
-jar 後面所跟的jar包的優先級別最高。如果指定了-jar選項,所有環境變量和命令行制定的搜索路徑都將被忽略。JVM APPClassloader將只會以jar包爲搜索範圍
https://www.cnblogs.com/zpbolgs/p/7267384.html
https://blog.csdn.net/sayyy/article/details/81120749
3、MANIFEST文件
https://www.jb51.net/article/131101.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章