java自定義ClassLoader加載指定的class文件操作
繼承ClassLoader并且重寫(xiě)findClass方法就可以自定義一個(gè)類加載器,具體什么是類加載器以及類加載器的加載過(guò)程與順序下次再說(shuō),下面給出一個(gè)小demo
首先定義一個(gè)類,比如MyTest,并且將其編譯成class文件,然后放到一個(gè)指定的文件夾下面,其中文件夾的最后幾層就是它的包名,這里我將這個(gè)編譯好的類放到 : /Users/allen/Desktop/cn/lijie/MyTest.class
package cn.lijie; public class MyTest { public void show() { System.out.println("show test!"); } }
自定義的類加載器:
public class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) { String myPath = "file:///Users/allen/Desktop/" + name.replace(".","/") + ".class"; System.out.println(myPath); byte[] cLassBytes = null; Path path = null; try { path = Paths.get(new URI(myPath)); cLassBytes = Files.readAllBytes(path); } catch (IOException | URISyntaxException e) { e.printStackTrace(); } Class clazz = defineClass(name, cLassBytes, 0, cLassBytes.length); return clazz; } }
測(cè)試的主函數(shù):
public class MainClass { public static void main(String[] args) throws ClassNotFoundException { MyClassLoader loader = new MyClassLoader(); Class<?> aClass = loader.findClass("cn.lijie.MyTest"); try { Object obj = aClass.newInstance(); Method method = aClass.getMethod("show"); method.invoke(obj); } catch (Exception e) { e.printStackTrace(); } } }
執(zhí)行主函數(shù),調(diào)用外部class的show方法:
補(bǔ)充:java遠(yuǎn)程加載class文件
1.在win上創(chuàng)建java文件并編譯
2.上傳到遠(yuǎn)程服務(wù)器
3.編寫(xiě)java代碼
準(zhǔn)備:
引入jar包 ganymed-ssh2-262.jar
1.加載外部class要定義自己的類加載器
2.使用內(nèi)存流
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import ch.ethz.ssh2.Connection; import ch.ethz.ssh2.SFTPInputStream; import ch.ethz.ssh2.SFTPv3Client; public class Fs{ public static void main(String[] args) throws Exception { OwnClassLoader ocl = new OwnClassLoader(); String ip,user,password; ip = "120.34.168.80";//自己的遠(yuǎn)程ip user = "root";//username password = "123456";//password ocl.login(ip, user, password); Object obj = ocl.loadeOthClass("/opt/4/tt.class");//class文件路徑 System.out.println(obj); Class c = obj.getClass(); Field f = c.getDeclaredField("age"); f.setAccessible(true); System.out.println("age:"+f.get(obj)); } } //自定義類加載器 class OwnClassLoader extends ClassLoader{ private Connection conn = null; //初始化鏈接 public Connection login(String ip,String user,String password){ Connection conn = null; try { //也可以new Connection(ip, port)創(chuàng)建對(duì)象,默認(rèn)22 conn = new Connection(ip); //連接遠(yuǎn)程服務(wù) conn.connect(); //使用用戶名和密碼登錄 conn.authenticateWithPassword(user, password); this.conn = conn; return conn; } catch (IOException e) { e.printStackTrace(); } return null; } //返回遠(yuǎn)程實(shí)例 public Object loadeOthClass(String url) throws Exception{ if(null==conn) throw new Exception("請(qǐng)初始化鏈接"); SFTPv3Client sc = new SFTPv3Client(conn);//創(chuàng)建ssh客戶端連接 InputStream is = new SFTPInputStream(sc.openFileRO(url));//創(chuàng)建輸入流 byte[] b = this.readClassFile(is); Class<?> c = super.defineClass(b, 0, b.length);//定義class return c.newInstance();//創(chuàng)建實(shí)例 } //讀取遠(yuǎn)程class文件 private byte[] readClassFile(InputStream is){ byte[] b = new byte[1024]; int len; ByteArrayOutputStream bos = null; try { bos = new ByteArrayOutputStream();//內(nèi)存流輸出 while((len=is.read(b))!=-1){ bos.write(b, 0, len); } b = bos.toByteArray(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { if(is!=null) is.close(); if(bos!=null) bos.close(); } catch (Exception e2) { // TODO: handle exception } } return b; } }
輸出結(jié)果:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
SpringBoot后端接收數(shù)組對(duì)象的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot后端接收數(shù)組對(duì)象的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11fastjson全局日期序列化設(shè)置導(dǎo)致JSONField失效問(wèn)題解決方案
這篇文章主要介紹了fastjson通過(guò)代碼指定全局序列化返回時(shí)間格式,導(dǎo)致使用JSONField注解標(biāo)注屬性的特殊日期返回格式失效問(wèn)題的解決方案2023-01-01Java日志框架用法及常見(jiàn)問(wèn)題解決方案
這篇文章主要介紹了Java日志框架用法及常見(jiàn)問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Spring中的后置處理器BeanPostProcessor詳解
這篇文章主要介紹了Spring中的后置處理器BeanPostProcessor詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08Java多線程中wait、notify、notifyAll使用詳解
這篇文章主要介紹了Java多線程中wait、notify、notifyAll使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05Java并發(fā)讀寫(xiě)鎖ReentrantReadWriteLock 使用場(chǎng)景
ReentrantReadWriteLock是Java中一種高效的讀寫(xiě)鎖,適用于讀多寫(xiě)少的并發(fā)場(chǎng)景,它通過(guò)允許多個(gè)線程同時(shí)讀取,但在寫(xiě)入時(shí)限制為單線程訪問(wèn),從而提高了程序的并發(fā)性和性能,本文給大家介紹Java并發(fā)讀寫(xiě)鎖ReentrantReadWriteLock 使用場(chǎng)景,感興趣的朋友跟隨小編一起看看吧2024-10-10Spring?@bean和@component注解區(qū)別
本文主要介紹了Spring?@bean和@component注解區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Java使用JMeter進(jìn)行高并發(fā)測(cè)試
軟件的壓力測(cè)試是一種保證軟件質(zhì)量的行為,本文主要介紹了Java使用JMeter進(jìn)行高并發(fā)測(cè)試,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11