Java---注解、類加載器-加強-實現運行任意目錄下class中加了@MyTest的空參方法

      網友投稿 711 2025-03-31

      做自己的類加載器


      虛擬機的核心是通過類加載器來加載.class文件,然后進行相應的解析執行。那么我們可以自己做類加載器,手動加載需要的.class以進行解析執行,從而擴展虛擬機的功能。

      以下內容摘自API文檔:

      應用程序需要實現 ClassLoader 的子類,以擴展 Java 虛擬機動態加載類的方式。

      網絡類加載器子類必須定義方法 findClass 和 loadClassData,以實現從網絡加載類。下載組成該類的字節后,它應該使用方法 defineClass 來創建類實例。

      代碼示例:

      自己的類加載器 MyClassLoader

      package cn.hncu; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.junit.Test; public class MyClassLoader extends ClassLoader{ public Class findClass(String name){ //name = "e:\cn\hncu\Person.class" Class c = null; FileInputStream in; byte[] b=null; //通過IO或網絡把字節碼數據讀取到buf[]當中。進一步地, //如果我們自己熟悉字節碼的生成格式,那么也可自己用程序生成。 //本例,我們是把硬盤中的一個外部字節碼文件的數據讀取到buf[]當中 //1 try { in = new FileInputStream(name); byte[] buf = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream();//字節流 int len=0; while((len=in.read(buf))!=-1){ baos.write(buf, 0, len); } in.close(); baos.close(); b = baos.toByteArray(); //2 ---1-2這里可以抽取出來寫一個loadClassData方法 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } c = defineClass("cn.hncu.Person", b, 0, b.length); return c; } @Test public void testClassData() throws ReflectiveOperationException{ String className="cn.hncu.Person"; //用Java的類加載器加載一個 Class c = Class.forName(className); Object obj = c.newInstance(); System.out.println(obj); System.out.println((Person)obj); System.out.println("-------------------"); className = "e:\cn\hncu\Person.class"; Class c2 = findClass(className); Object obj2 = c2.newInstance(); System.out.println(obj2); System.out.println((Person)obj2);//這句是有問題的 //※不同類加載器加載的對象是無法強轉---可以理解是不同的生存空間 //Person p2 = (Person) obj2;//會掛的。 //因為obj2的生存空間是MyClassLoader,而Person的生成空間是AppClassLoader //System.out.println(p2); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      測試結果:

      看,最后那句不能輸出吧。

      因為不是一個類加載器的。

      作自己的測試工具MyJUnit

      (注解與反射共同使用的案例 )

      相關說明:

      1)JUnit用的是@Test注解,我們用@MyTest注解。

      2)JUnit已經嵌入到MyEclipse當中,我們自己的MyJUnit只要能獨立運行就可以(不嵌入),同時這樣我們也不方便在MyJUnit中以參數方式接收到被測試類的類名與方法名,只能以鍵盤輸入的方式接收。

      3)JUnit能實現指定單個方法來調用執行,由于不能利用MyEclipse傳參,因此我們在MyJUnit程序中遍歷所有的方法并通過判斷是否聲明@MyTest注解來決定是否調用執行該方法。

      下面實現了運行任意目錄下的實現了@MyTest注解的方法:

      需要輸入絕對路徑名和類的完整名字。

      注解:@MyTest

      package cn.hncu.myJunit; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)//運行時也存在,必須要加這個 @Target (ElementType.METHOD)//限制注解只能加在方法上 public @interface MyTest { }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      測試類:TestPerson

      package cn.hncu.myJunit; /** * 測試用的 * @author 陳浩翔 * * @version 1.0 2016-5-6 */ public class TestPerson { public void run1(){ System.out.println("run1..."); } @MyTest public void run2(){ System.out.println("run2..."); } public void run3(){ System.out.println("run3..."); } @MyTest public void run4(){ System.out.println("run4..."); } public void run5(){ System.out.println("run5..."); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      Java---注解、類加載器-加強-實現運行任意目錄下class中加了@MyTest的空參方法

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      MyClassLoader類:自己寫的類加載器

      package cn.hncu.myJunit; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /** * 自己寫的類加載器 * @author 陳浩翔 * * @version 1.0 2016-5-6 */ public class MyClassLoader extends ClassLoader{ //我把它分成2個方法寫了。 public Class findClass(String name, String className) { try { byte b[] = loadClassData(name); Class c = defineClass(className, b, 0, b.length); return c; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } private static byte[] loadClassData(String name) throws IOException { byte buf[] = new byte[1024]; FileInputStream in = new FileInputStream(name); ByteArrayOutputStream out = new ByteArrayOutputStream(); int len=0; while((len=in.read(buf))!=-1){ out.write(buf, 0, len); } in.close(); out.close(); byte b[] = out.toByteArray(); return b; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      main方法類:

      package cn.hncu.myJunit; import java.lang.reflect.Method; import java.util.Scanner; import cn.hncu.myJunit.MyClassLoader; /** * @author 陳浩翔 * @version 1.0 2016-5-6 */ public class MyJunit { public static void main(String[] args) throws ReflectiveOperationException { Scanner sc = new Scanner(System.in); System.out.println("請輸入需要運行的類的絕對路徑(路徑中不能有空格,需要類的.class文件):"); String name = sc.next(); System.out.println("請輸入類的名稱(包含包名):"); String className = sc.next(); Class c = (new MyClassLoader()).findClass(name, className); //獲得那個類了。 //那個類必須要有空參構造方法 Object obj = c.newInstance(); //獲得這個類所有聲明的方法,包括私有的 Method ms[] = c.getDeclaredMethods(); for(Method m:ms){ if(m.isAnnotationPresent(MyTest.class)){ m.invoke(obj, null); } } } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      運行測試結果:

      現在我把class文件移動到D盤了。

      再看運行結果:

      這個可以有很多改進的地方,就比如每次輸入路徑都很麻煩,

      我們可以做一個圖形界面,讓我們自己選擇。

      這樣就方便多了。

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:中小制造公司生產管理制度(小型企業生產管理制度)
      下一篇:企業生產管理前景分析 - 走向未來的成功之路
      相關文章
      久久久久亚洲精品中文字幕| 亚洲欧美国产欧美色欲| 亚洲国产精品日韩av不卡在线| 久久精品国产亚洲av水果派 | 亚洲AV成人精品日韩一区18p| 亚洲成a人片在线不卡| 77777_亚洲午夜久久多人| 亚洲国产精品一区二区久久| 久久久综合亚洲色一区二区三区 | 亚洲精品视频在线观看你懂的| 国产亚洲视频在线| 色综合久久精品亚洲国产| 亚洲av无一区二区三区| 亚洲AV综合色区无码一二三区| 亚洲精品无码专区久久| 亚洲中文字幕久久精品无码A| 亚洲精品天堂在线观看| 日韩亚洲国产综合高清| 亚洲最大的成人网站| 亚洲欧美中文日韩视频| 亚洲aⅴ无码专区在线观看| 国产亚洲精品AAAA片APP| 青青青亚洲精品国产| 偷自拍亚洲视频在线观看| 亚洲电影日韩精品| 久久国产成人亚洲精品影院| 美腿丝袜亚洲综合| 日韩亚洲人成在线综合日本 | 国产精品亚洲AV三区| 全亚洲最新黄色特级网站 | 亚洲永久中文字幕在线| 亚洲免费电影网站| 亚洲影院天堂中文av色| 国产精品无码亚洲一区二区三区| 老牛精品亚洲成av人片| 国产成人亚洲精品91专区手机| 亚洲精品乱码久久久久久| 亚洲A∨无码一区二区三区| 亚洲欧洲精品在线| 亚洲中文字幕无码mv| 四虎亚洲国产成人久久精品|