使用反射机制可以取得类的方法的对象代表,则是一个java.lang.reflect.Method的实例。
如有一个实体类:
public class Student {
private String name;
private int score;
public Student() {
}
public Student(String name, int score) {
super();
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return name+":"+score;
}
}
现在新建一个主函数,对其进行操作,主要操作如下:
1、动态加载Student类,并生成该类的一个待操作对象:
//动态加载Student类
Class c = Class.forName("Student");
2、利用反射机制去除函数对象:
//利用反射机制取出要使用的函数
Class[] param1 = {String.class};//指定参数类型
Method setNameMethod = c.getMethod("setName", param1);
注意:
在制定参数类型是=时:基本类型用其包装类的.TYPE,而参数类型为包装类时用.class
3、执行方法
//方法的执行
Object[] arg1 = {"name"};
setNameMethod.invoke(o, arg1);
在此期间需要捕获异常:
catch (ClassNotFoundException e) {
System.out.println("加载类错误");
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
System.out.println("未找到该方法");
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("类初始化失败");
e.printStackTrace();
} catch (IllegalArgumentException e) {
System.out.println("参数错误");
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("方法执行出错");
e.printStackTrace();
}
我们也可以突破函数的存取限制来调用受保护甚至是私有的方法:
1、将上面的实体类的某方法setName设置为私有的
2、当我们继续以上面的方式运行时就会出现以下错误:
未找到该方法
java.lang.NoSuchMethodException: Student.setName(java.lang.String)
at java.lang.Class.getMethod(Class.java:1605)
at T2.main(T2.java:18)
3、此时我们应该这样取到并操作我们要的方法:
//利用反射机制取出要使用的函数
Class[] param1 = {String.class};//指定参数类型
Method setNameMethod = c.getDeclaredMethod("setName", param1);
setNameMethod.setAccessible(true); //否则会产生java.lang.IllegalAccessException的异常
尽管直接存取类的原成员是不推荐的,但仍可一类似上面的方法来进行相关操作:
public class Student {
public String name;
private int score;
@Override
public String toString() {
return name+":"+score;
}
}
import java.lang.reflect.Field;
public class T2 {
/**
* @param args
*/
public static void main(String[] args) {
try {
Class c = Class.forName("Student"); //动态加载
Object o = c.newInstance(); //生成实例
Field nameField = c.getField("name"); //获取public成员
nameField.set(o, "name");
Field scoreField = c.getDeclaredField("score"); //获取权限限制成员
scoreField.setAccessible(true); //设置能访问
scoreField.setInt(o, 90);
System.out.println(o);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
对于反射机制中的数组对象,我们需要利用到 java.lang.reflect.Array ,简单的示例如下:
import java.lang.reflect.Array;
public class T4 {
/**
* @param args
*/
public static void main(String[] args) {
Class c= String.class;
Object oArr = Array.newInstance(c, 5);
for (int i = 0; i < 5; i++) {
Array.set(oArr, i, i+" ");
}
for (int i = 0; i < 5; i++) {
System.out.print(Array.get(oArr, i));
}
System.out.println();
String[] strs = (String[]) oArr;
for (String string : strs) {
System.out.print(string+" ");
}
}
}