国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
關(guān)于class.forname和contextClassloader

自從java1.2開始,java的classloader有了階層體系。

這是我之前說過的,最初的例如rt.jar里面的class,比如Object是由c++寫的bootstrapclassloader來載入的。

bootstrapclassloader的孩子extclassloader搜索jre里面的用于存放java擴(kuò)展jar的目錄負(fù)責(zé)載入其中的class。

然后是appclassloader或者叫做systemclassloader,是搜索CLASSPATH環(huán)境變量或者-cp參數(shù)里面指定的目錄和壓縮文件。

任何一個(gè)class的載入都需要一個(gè)classloader,而且一旦載入就無法改變,并且如果不加指定或者直接使用,都會(huì)默認(rèn)使用caller的classloader來載入用到的class。

而1.2里面classloader階層迭代體系是,每次需要載入時(shí),首先看父親能不能載入,也就是說是從根往下找的,在上層找到就不往下找了,這樣的機(jī)制能夠保證安全性。

class.forname為我們java提供了強(qiáng)大的靈活性,我們甚至在構(gòu)建系統(tǒng)時(shí),即將運(yùn)行的代碼不存在也沒有關(guān)系。

public class DynamicLoader
{
public static void main(String[] args)
throws Exception
{
Class toRun = Class.forName(args[0]);
String[] newArgs = scrubArgs(args);
Method mainMethod = findMain(toRun);
mainMethod.invoke(null, new Object[] { newArgs });
}
private static String[] scrubArgs(String[] args)
{
String[] toReturn = new String[args.length-1];
for (int i=1; i<args.length; i++)
{
toReturn[i-1] = args[i].toLowerCase();
}
return toReturn;
}
private static Method findMain(Class clazz)
throws Exception
{
Method[] methods = clazz.getMethods();
for (int i=0; i<methods.length; i++)
{
if (methods[i].getName().equals("main"))
return methods[i];
}
return null;
}
}

像這個(gè)程序,可以用來運(yùn)行任何的java程序,例如我們寫了一個(gè)Echo:
public class Echo
{
public static void main (String args[])
{
for (int i=0; i<args.length; i++)
{
System.out.println("Echo arg"+i+" = "+args[i]);
}
}
}

我們可以
java DynamicLoader Echo ONE TWO THREE

輸出:
Echo arg0 = one
Echo arg1 = two
Echo arg2 = three

于是我們將DynamicLoader打包成jar,扔到ext目錄,再次運(yùn)行:
java DynamicLoader Echo ONE TWO THREE
Exception in thread "main" java.lang.ClassNotFoundException: Echo
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:191)
at java.lang.ClassLoader.loadClass(ClassLoader.java:280)
at java.lang.ClassLoader.loadClass(ClassLoader.java:237)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:124)
at DynamicLoader.main(DynamicLoader.java:8)

怎么回事呢?
明明當(dāng)前目錄下有Echo.class???

這就是階層迭代機(jī)制造成的,載入DynamicLoader的classloader是ext,用class.forname默認(rèn)也會(huì)使用extclassloader,往上只有bootstrapclassloader,根本找不到了。

那怎么辦呢?

我們只有使用
Thread t = Thread.currentThread();
ClassLoader cl = t.getContextClassLoader();
Class toRun = cl.loadClass(args[0]);

contextClassLoader來做,或者我們直接指定是systemclassloader
Class.forName(args[0],
true,
ClassLoader.getSystemClassLoader());

這里用了三個(gè)參數(shù)的forName,只有用以上兩種辦法,改變載入class的classloader,才能找得到。

contextClassloader是和線程Thread掛鉤的,一個(gè)線程只有一個(gè),并且可以設(shè)定安全機(jī)制,如果不加以改換,默認(rèn)就是systemclassloader,而且這個(gè)線程創(chuàng)建出來的線程會(huì)保留創(chuàng)建者的classloader。

這些在容器實(shí)現(xiàn)和企業(yè)級(jí)服務(wù)器方面或者像jndi,rmi等技術(shù)上使用得非常多,光是tomcat最深的classloader是第七層,websphere就更不用說了。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
走出ClassLoader的迷宮
老大難的 Java ClassLoader 再不理解就老了
Java類別載入器
Java學(xué)習(xí)-注解和反射
淺析ContextClassLoader
Java類加載器
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服