白桦的天空

第一次的心动,永远的心痛!
  首页  :: 新随笔  :: 联系 :: 管理

通过反射动态使用Java类

Posted on 2008-05-29 12:39  白桦的天空  阅读(202)  评论(0编辑  收藏  举报

一.已知一个类的名字及其class文件,如何使用此类?

1.如果此类位于一个已打包的jar文件中,按如下方法调用:
URL url = new URL("file:/E:/Work/Projects/Output/FrameWork.jar");
URLClassLoader ul = new URLClassLoader(new URL[]{url});
Class aClass = ul.loadClass("com.hdpan.exercise.loader.ProduceObject");
Object obj = aClass.newInstance();

注意的是URLClassLoader.loadClass()方法的参数要包括package的名字,例如这里面如果写成ProduceObject就是错误的。

2.如果此类是一个class文件,位于一个文件夹中,按如下方法调用:
首先要确认的是class的package的名字与目录名应该一致。
URL url = new URL("file:/E:/Work/Projects/FrameWork/bin");
URLClassLoader ul = new URLClassLoader(new URL[]{url});
Class aClass = ul.loadClass("com.hdpan.exercise.loader.ProduceObject");
Object obj = aClass.newInstance();
这里面的URL的路径指到package名的上一层目录位置,例如这里如果写成file:/E:/Work/Projects/FrameWork/bin/com/hdpan/exercise/loader就是错误的

Class这个类中还有许多的get方法可以使用。

二.如何打印class中的所有方法?
Method[] md = aClass.getDeclaredMethods();
for (int i = 0; i < md.length; i++){
System.out.println(md.getName());
}
md.getModifiers();
md.getReturnType();
md.getParameterTypes();
md.getExceptionTypes();

Method这个类中还有许多的属性可以get得到。

如果有两个方法的Name是一样的,但是参数不一样:
Method md = aClass.getMethod("setField1",new Class[]{Integer.TYPE});
第一个参数是方法的名字,第二个参数是一个数组,如果是基本数据类型的话,使用其外覆类的类型,例如int使用Integer.Type,float使用Float.Type

例如,如果类中是这样的定义的:
public void setField1(int field1,String info) {
this.field1 = field1;
System.out.println(info);
}

那么在使用的时候:
Method md = clas.getMethod("setField1",new Class[]{Integer.TYPE,String.class});

三.如何调用class中的方法?
调用方法:

Object obj = aClass.newInstance();
Method mds = aClass.getMethod("setField1",new Class[]{Integer.TYPE});
mds.invoke(obj,new Object[]{new Integer(5)});

对invoke方法,第一个参数是方法所在的对象,如果方法是static的,那么此处可以是null,如果方法不是static的,但是此处是Null的话将会出现NullPointerException
第二参数是方法所需要的参数的对象数组,如果是基本数据类型的话,使用其外覆类的类型,例如int使用Integer.Type,float使用Float.Type

例如,如果类中是这样的定义的::
public void setField1(int field1,String info) {
this.field1 = field1;
System.out.println(info);
}
那么在使用的时候:
Object obj = aClass.newInstance();
Method md = aClass.getMethod("setField1",new Class[]{Integer.TYPE,String.class});
md.invoke(obj,new Object[]{new Integer(5),"This is a Test"});

如果想取得方法的返回值:
public int getField1() {
return field1;
}

那么在使用的时候:
mds = aClass.getMethod("getField1",null);
Integer integer = (Integer)mds.invoke(obj,null);
System.out.println(integer.intValue());

Method方法返回的类型是Object,根据具体的方法返回值类型,将其下溯到具体的类型。

源程序:
ProduceObject.java
=================================
//ProduceObject.java开始
package com.hdpan.exercise.loader;

public class ProduceObject {

public int getField1() {
return field1;
}

public void setField1(int field1) {
this.field1 = field1;
}
public void setField1(int field1,String info) {
this.field1 = field1;
System.out.println(info);
}

public static double getField2() {
return field2;
}

public static void setField2(double field2) {
ProduceObject.field2 = field2;
}
private int field1;
private static double field2;

public static void main(String[] args) {
}
}
//ProduceObject.java结束
=========================

TestLoader.java
=========================
//TestLoader.java开始
package com.hdpan.exercise.loader;

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

public class TestLoader {

public static void main(String[] args) throws Exception {
try {
//URL url = new URL("file:/E:/Work/Projects/Output/FrameWork.jar");
URL url = new URL("file:/E:/Work/Projects/FrameWork/bin/com/hdpan/exercise/loader");

URLClassLoader ul = new URLClassLoader(new URL[]{url});

//Class clas = ul.loadClass("ProduceObject");
Class aClass = ul.loadClass("com.hdpan.exercise.loader.ProduceObject");

Object obj = aClass.newInstance();
Method mds = aClass.getMethod("setField1",new Class[]{Integer.TYPE,String.class});
mds.invoke(obj,new Object[]{new Integer(5),"haha"});

mds = aClass.getMethod("getField1",null);
Integer integer = (Integer)mds.invoke(obj,null);
System.out.println(integer.intValue());
//System.out.println(((com.hdpan.exercise.loader.ProduceObject)obj).getField1());

Method[] md = aClass.getDeclaredMethods();
for (int i = 0; i < md.length; i++){
System.out.println(md.getName());
}

} catch (Exception e) {
System.out.println(e);
}

}
}
//TestLoader.java开始