2012-11-09 15 views
1

方法DriverManager.getCallerClassLoader()java.sql.DriverManageris declared asnative。我知道應用程序中的所有類加載器引用在當前正在執行的JVM中都可用。此外,我對本地方法的基本理解是,它用於調用本地庫中定義的方法,並且它們在JVM執行環境之外執行。爲什麼java.sql.DriverManager.getCallerClassLoader()是本地的?

我的問題是,DriverManager.getCallerClassLoader()需要什麼,這需要它的實現是本地的?

回答

2

我對本地方法的基本理解是,它用來調用本機庫

這是正確的,本地方法表示這是一個本地編譯庫

的部分代碼的調用定義的方法

,他們執行JVM運行環境

這就是外面那提ve方法通常會這樣做。也就是說,Java用戶編寫的本地方法。但是,本機方法不限於可以執行的操作:一旦您處於JVM之外,就可以按照自己的意願進行操作。事實上,Java的內置類(如Class<T>)在很大程度上依賴於這樣做的能力,其中幾十個方法遍佈其Java代碼。

其中一種方法是封裝私有java.lang.Class<T>.getClassLoader0(是的,零)。 ClassLoader.getCallerClassLoader的實現最終是指這種方法,它查詢JVM的內部以獲取類加載器。

注意DriverManager不能將呼叫轉接至ClassLoader.getCallerClassLoader,因爲那將返回DriverManager的類加載器(因爲DriverManager將是getCallerClassLoader調用者)。 DriverManager不可能重複ClassLoadergetCallerClassLoader的「魔術」,因爲它位於不同的包中(即不在java.lang中),所以Class<T>.getClasLoader0不可訪問。這就是爲什麼它被迫將getCallerClassLoader移動到native的領土,在那裏本地代碼可以獲得調用類並無需限制地獲取其類加載器。

+0

因此,'DriverManager'需要'ClassLoader.getCallerClassLoader'的「魔術」,因此需要本地方法。這回答了我的問題。這引起了另外一個問題,那就是'DriverManager'需要什麼「魔力」?如果你檢查'DriverManager'的源代碼,它最終會檢查本地方法返回的類加載器,如果發現空使用'Thread.currentThread()。getContextClassLoader()'這不是本地的! – Santosh

+0

@Santosh'Thread'在'java.lang'中,它可以(並且確實)調用'ClassLoader.getCallerClassLoader()',它[調用](http://grepcode.com/file/repository.grepcode.com /java/root/jdk/openjdk/6-b14/java/lang/ClassLoader.java#ClassLoader.getCallerClassLoader%28%29)是'native'的相同'getClassLoader0'。 – dasblinkenlight

+0

啊!我的錯。應該親眼看到源代碼。謝謝。 – Santosh