如何改變jar包某個(gè)類的運(yùn)行方式

這篇文章主要介紹“如何改變jar包某個(gè)類的運(yùn)行方式”,在日常操作中,相信很多人在如何改變jar包某個(gè)類的運(yùn)行方式問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”如何改變jar包某個(gè)類的運(yùn)行方式”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站制作、網(wǎng)站建設(shè)與策劃設(shè)計(jì),湛江網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:湛江等地區(qū)。湛江做網(wǎng)站價(jià)格咨詢:18982081108

例如:

有類 Feature

Java代碼

public class Feature {             private String content;             public void show() {             System.out.println(this.content);         }     }

及類 Function

Java代碼

public class Function {             private Feature f;             public void show() {             this.f.show();         }              }

測(cè)試類 Test,運(yùn)行結(jié)果為 null . 而你想讓他輸出hello kitty

Java代碼

public class Test {             /**         * @param args         */        public static void main(String[] args) {             Function function = new Function();             function.show();         }         }

***想到的方法是就是直接建一個(gè)同包同名類,在你的eclipse或者其它編譯環(huán)境下;然后把相關(guān)方法,改成自己想要的方法;如下:

Java代碼

public class Feature {             private String content;             public Feature(){             this.content = "hello kitty";         }             public void show() {             System.out.println(this.content);         }     }

然后,你會(huì)發(fā)現(xiàn),使用的是你的class吖,而不是jar包里的吖.

但是,如果你的程序也打成jar包,和原jar一起運(yùn)跑,會(huì)是什么情況呢;

你可能發(fā)現(xiàn),會(huì)輸出 空,如果運(yùn)氣好,也可能 輸出 hello kitty ;

為啥呢? 因?yàn)楫?dāng)有同包同名類時(shí),classLoader總會(huì)嘗試先加載到一個(gè),而且加載到這個(gè)class文件后,后面就不會(huì)再加載;這個(gè)先加載到的類一般和classpath設(shè)置的先后有關(guān);

在eclipse環(huán)境下,會(huì)先加載編輯器下的類,然后優(yōu)先加載,先導(dǎo)入的類庫;

如果先加載到你的類,那么就會(huì)輸出 "hellokitty".

假如需要在生產(chǎn)環(huán)境指定加載你的類,

而且,

你無法預(yù)知客戶如何設(shè)置classPath的先后順序,那么,要怎么辦呢?

可否自己寫一個(gè)classLoader只加載目標(biāo)類,而讓你的調(diào)用程序在此classLoader環(huán)境下運(yùn)行?

Let us try try : 先寫出這個(gè)特別的classLoader

Java代碼

public class HoneyLoader extends URLClassLoader {             public HoneyLoader(URL[] urls, ClassLoader parent){             super(urls, parent);         }             public synchronized Class loadClass(String name) throws ClassNotFoundException {             Class c = findLoadedClass(name);             if (c != null) {                 return c;             }     //先自己在指定位置(通過urls指定)找,找不到交給父類             try {                 c = this.findClass(name);             } catch (Exception e) {                 c = super.loadClass(name);             }             return c;         }     }

回到我們的測(cè)試類,修改如下

Java代碼

public class Test {             public static void main(String[] args) throws Exception {             // 根據(jù)jar包名稱,獲取我們需要的jar包的名稱的url             String jarName = "feature2.jar";             URL url = null;                 ClassLoader loader = Thread.currentThread().getContextClassLoader();             Enumeration urls = loader.getResources("Feature.class");             int i = 0;             while (urls.hasMoreElements()) {                 url = urls.nextElement();                 i = url.getPath().indexOf(jarName);                 if (i > -1) {                     break;                 }             }                 // 用honeyLoader啟動(dòng)我們的運(yùn)行環(huán)境             ClassLoader myLoader = new HoneyLoader(new URL[] { new URL(url.getPath().substring(0, i) + jarName) }, loader);             Object object = myLoader.loadClass("Feature").newInstance();             object.getClass().getMethod("show").invoke(object);             }

運(yùn)行結(jié)果:

Java代碼

hello kitty

用classLoader的方法,將建立一個(gè)小的運(yùn)行機(jī)制,和業(yè)務(wù)代碼的相關(guān)性很低,冗余代碼多;

而且,新建的和原類相同的包名和類不便于維護(hù);

有什么更好的方法么?

對(duì)于(一)中描述的需求,其實(shí),我們只需改變下Feature的私有屬性content,是否可以通過反射來實(shí)現(xiàn)呢?

嘗試以下代碼:

Java代碼

public class Test {             // 獲取object 的屬性 fieldName         public static Field getField(Object object, String fieldName) throws Exception {             Field field = object.getClass().getDeclaredField(fieldName);             return field;         }             public static void main(String[] args) throws Exception {             Function function = new Function();             // 獲取function的feature             Field f_feature = getField(function, "f");                 // 通過feature 獲取 其屬性 content             f_feature.setAccessible(true);             Field f_function = getField(f_feature.get(function), "content");                 // 改變content的內(nèi)容             f_function.setAccessible(true);             f_function.set(f_feature.get(function), "hello kitty");                 function.show();         }     }

執(zhí)行,得到結(jié)果

Java代碼

hello kitty

冗余代碼減少,目的更加明確了,但對(duì)于改變的業(yè)務(wù)代碼,任然不清晰;不容易維護(hù);

通常,如果我們要得到有我們的特性的類,通常用繼承的方法,但是有時(shí)候,會(huì)發(fā)現(xiàn),如果是你要調(diào)用的調(diào)用的調(diào)用的類,要改變一點(diǎn)動(dòng)作,那你為了改調(diào)用的調(diào)用的調(diào)用,不得不繼承調(diào)用和調(diào)用的調(diào)用;

假如我們只改變目標(biāo)類,只繼承目標(biāo)類,結(jié)合反射的方式,改調(diào)用,是否可行呢?

例如,繼承Feature創(chuàng)建類MyFeature

Java代碼

public class MyFeature extends Feature {             private String mycontent;             public MyFeature(){             this.mycontent = "hello kitty";         }             public void show() {             System.out.println(this.mycontent);         }     }

這樣我們改變的邏輯清晰很多,容易維護(hù),我們?cè)賮硇薷南耇est類

Java代碼

public class Test {             // 獲取object 的屬性 fieldName         public static Field getField(Object object, String fieldName) throws Exception {             Field field = object.getClass().getDeclaredField(fieldName);             return field;         }             public static void main(String[] args) throws Exception {             Function function = new Function();             // 獲取function的feature             Field f_feature = getField(function, "f");                 // 改變feature的內(nèi)容             f_feature.setAccessible(true);             f_feature.set(function, new MyFeature());                 function.show();         }     }

此時(shí),Test的邏輯也清晰很多,我們可以清楚的看到,我們需要改變哪個(gè)類

運(yùn)行一下,看下結(jié)果

Java代碼

hello kitty

到此,關(guān)于“如何改變jar包某個(gè)類的運(yùn)行方式”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

新聞標(biāo)題:如何改變jar包某個(gè)類的運(yùn)行方式
標(biāo)題路徑:http://bm7419.com/article38/pscdpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司網(wǎng)站改版、網(wǎng)站導(dǎo)航小程序開發(fā)App設(shè)計(jì)、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司