命名空間及其作用
每個(gè)類(lèi)裝載器有自己的命名空間,命名空間由所有以此裝載器為創(chuàng)始類(lèi)裝載器的類(lèi)組成。不同命名空間的兩個(gè)類(lèi)是不可見(jiàn)的,但只要得到類(lèi)所對(duì)應(yīng)的Class對(duì)象的reference,還是可以訪問(wèn)另一命名空間的類(lèi)。
例2演示了一個(gè)命名空間的類(lèi)如何使用另一命名空間的類(lèi)。在例子中,LoaderSample2由系統(tǒng)類(lèi)裝載器裝載,LoaderSample3由自定義的裝載器loader負(fù)責(zé)裝載,兩個(gè)類(lèi)不在同一命名空間,但LoaderSample2得到了LoaderSample3所對(duì)應(yīng)的Class對(duì)象的reference,所以它可以訪問(wèn)LoaderSampl3中公共的成員(如age)。
例2不同命名空間的類(lèi)的訪問(wèn)
/*LoaderSample2.java*/
import java.net.*;
import java.lang.reflect.*;
public class LoaderSample2 {
??? public static void main(String[] args) {
??????? try {
??????????? String path = System.getProperty("user.dir");
??????????? URL[] us = {new URL("file://" + path + "/sub/")};
??????????? ClassLoader loader = new URLClassLoader(us);
??????????? Class c = loader.loadClass("LoaderSample3");
??????????? Object o = c.newInstance();
??????????? Field f = c.getField("age");
??????????? int age = f.getInt(o);
??????????? System.out.println("age is " + age);
??????? } catch (Exception e) {
??????????? e.printStackTrace();
??????? }
??? }
}
/*sub/Loadersample3.java*/
public class LoaderSample3 {
??? static {
??????? System.out.println("LoaderSample3 loaded");
??? }
??? public int age = 30;
}
編譯:javac LoaderSample2.java; javac sub/LoaderSample3.java
運(yùn)行:java LoaderSample2
LoaderSample3 loaded age is 30
從運(yùn)行結(jié)果中可以看出,在類(lèi)LoaderSample2中可以創(chuàng)建處于另一命名空間的類(lèi)LoaderSample3中的對(duì)象并可以訪問(wèn)其公共成員age。
運(yùn)行時(shí)包(runtime package)
由同一類(lèi)裝載器定義裝載的屬于相同包的類(lèi)組成了運(yùn)行時(shí)包,決定兩個(gè)類(lèi)是不是屬于同一個(gè)運(yùn)行時(shí)包,不僅要看它們的包名是否相同,還要看的定義類(lèi)裝載器是否相同。只有屬于同一運(yùn)行時(shí)包的類(lèi)才能互相訪問(wèn)包可見(jiàn)的類(lèi)和成員。這樣的限制避免了用戶(hù)自己的代碼冒充核心類(lèi)庫(kù)的類(lèi)訪問(wèn)核心類(lèi)庫(kù)包可見(jiàn)成員的情況。假設(shè)用戶(hù)自己定義了一個(gè)類(lèi)java.lang.Yes,并用用戶(hù)自定義的類(lèi)裝載器裝載,由于java.lang.Yes和核心類(lèi)庫(kù)java.lang.*由不同的裝載器裝載,它們屬于不同的運(yùn)行時(shí)包,所以java.lang.Yes不能訪問(wèn)核心類(lèi)庫(kù)java.lang中類(lèi)的包可見(jiàn)的成員。
總結(jié)
在簡(jiǎn)單討論了類(lèi)裝載器,parent delegation模型,命名空間,運(yùn)行時(shí)包后,相信大家已經(jīng)對(duì)它們的作用有了一定的了解。命名空間并沒(méi)有完全禁止屬于不同空間的類(lèi)的互相訪問(wèn),雙親委托模型加強(qiáng)了Java的安全,運(yùn)行時(shí)包增加了對(duì)包可見(jiàn)成員的保護(hù)。