首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java 反射 加载指定目录上的Class文件

2012-10-09 
java 反射加载指定目录下的Class文件1????最近由于公司android 客服端的兄弟想做 动态扩展android应用,而

java 反射 加载指定目录下的Class文件

1????最近由于公司android 客服端的兄弟想做 动态扩展android应用,而不通过 重新发布版本来来实现,所以就考虑到用java的反射 加载指定的类

?

???? A 一般加载类的? Class.froName的方法,这个方法是加载 已经集成或者导入到 项目下的jar 下面的类

?

????????? 如是 找到Class类,发现只有 Class.forName的方法

?

???? 如是去找ClassLoader 发现 一个defineClass? 的方法可以 接受字节数组,来生产Class对象,但是

?

? 在编码工具中Eclipse 去实例这个类,在调用这个方法是,竟然发现竟然说这个方法不存在,开始我以为是文档的问题,

?

后面一想 ,java 中有许多方法是提供给jvm虚拟机用的,编码工具对其进行的过滤,后面同事收到一篇同样需求的代码,

?

?

一看才想明白,既然不能在外部调用,如果继承这个类,再重写这个方法,就可以实现这样的需求,额,有时候看样子还是

?

想的不够

?

好了,看实现类代码

public class ClassLoaderExpand extends ClassLoader {/** * name class 类的文件名 */@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] datas = loadClassData(name);  return defineClass(name, datas, 0, datas.length);  }// 指定文件目录private String location; public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}protected byte[] loadClassData(String name)      {      FileInputStream fis = null;       byte[] datas = null;      try      {         fis = new FileInputStream(location+name+".class");         ByteArrayOutputStream bos = new ByteArrayOutputStream();          int b;          while( (b=fis.read())!=-1 )           {           bos.write(b);           }          datas = bos.toByteArray();          bos.close();       }catch(Exception e)       {           e.printStackTrace();       }       finally       {           if(fis != null)          try           {               fis.close();          } catch (IOException e)           {               e.printStackTrace();           }       }       return datas;    }  }

?

再看调用方式

//实例扩展类ClassLoaderExpand clod=new ClassLoaderExpand();//指定java class 文件目录clod.setLocation("E:/service/");try {//调用 通过字节流生产java类    Class cl=clod.findClass("Test");        //这里是调用带参数的方法,参数是数组对象Method method=cl.getMethod("test2",new Class[]{String [].class});//如果这里 调用的是 实例方法 和以上的一样,只是后面调用Method的invoke不一样System.out.println(method.getName());method.invoke(cl, new Object[]{new String []{}});//这里的cl 是 生产的类,为什么这里没有  cl.newInstance() ,因为调用的test2 是静态方法,如果不是静态方法,需要用一下的//method.invoke(cl.newInstance(), new Object[]{new String []{}});} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}

?

?

好了再看 Test 类中有哪些方法

public  void test1() {System.out.println("-----------1---------");System.out.println("asdfasdfasdfasd");}public static void test2(String[] args) {System.out.println("----------2----------");System.out.println("asdfasdfasdfasd");}

?

?


----------------------承接java 项目
java web ,
java 中间件开发
电话 13534066735
QQ?? 239052343

?

1 楼 pengchang_2008 2012-06-14   您这个方法还是有用得,不过假如这个Test类不是默认包的,具有某个包名的话,需要怎么改动您的代码跑起来,我试了几种办法,就是不能调用一个含有包的代码,请指教! 2 楼 chen422520 2012-06-25   pengchang_2008 写道您这个方法还是有用得,不过假如这个Test类不是默认包的,具有某个包名的话,需要怎么改动您的代码跑起来,我试了几种办法,就是不能调用一个含有包的代码,请指教!


你只需要加上包名 就好了 Class cl=clod.findClass("Test");  这里的Test直接是类名,你如果是带有包的,可以在这里加上

热点排行