好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

java自定义ClassLoader加载指定的class文件操作

继承classloader并且重写findclass方法就可以自定义一个类加载器,具体什么是类加载器以及类加载器的加载过程与顺序下次再说,下面给出一个小demo

首先定义一个类,比如mytest,并且将其编译成class文件,然后放到一个指定的文件夹下面,其中文件夹的最后几层就是它的包名,这里我将这个编译好的类放到 : /users/allen/desktop/cn/lijie/mytest.class

?

1

2

3

4

5

6

package cn.lijie;

public class mytest {

   public void show() {

     system.out.println( "show test!" );

   }

}

自定义的类加载器:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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;

   }

}

测试的主函数:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

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();

     }

   }

}

执行主函数,调用外部class的show方法:

补充:java远程加载class文件

1.在win上创建java文件并编译

2.上传到远程服务器

3.编写java代码

准备:

引入jar包 ganymed-ssh2-262.jar

1.加载外部class要定义自己的类加载器

2.使用内存流

?

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

69

70

71

72

73

74

75

76

77

78

79

80

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" ; //自己的远程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)创建对象,默认22

   conn = new connection(ip);

   //连接远程服务

   conn.connect();

   //使用用户名和密码登录

   conn.authenticatewithpassword(user, password);

   this .conn = conn;

      return conn;

  } catch (ioexception e) { 

   e.printstacktrace();

   }

   return null ;

  }

  //返回远程实例

  public object loadeothclass(string url) throws exception{

  if ( null ==conn)

   throw new exception( "请初始化链接" );

  sftpv3client sc = new sftpv3client(conn); //创建ssh客户端连接

  inputstream is = new sftpinputstream(sc.openfilero(url)); //创建输入流

  byte [] b = this .readclassfile(is);

  class <?> c = super .defineclass(b, 0 , b.length); //定义class

  return c.newinstance(); //创建实例

  }

  //读取远程class文件

  private byte [] readclassfile(inputstream is){

  byte [] b = new byte [ 1024 ];

  int len;

  bytearrayoutputstream bos = null ;

  try {

   bos = new bytearrayoutputstream(); //内存流输出

   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;

  }

}

输出结果:

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

原文链接:https://blog.csdn.net/qq_20641565/article/details/78744677

查看更多关于java自定义ClassLoader加载指定的class文件操作的详细内容...

  阅读:18次