反射:
Class c = Class.forName ("java.lang.Integer");
这条语句得到一个 Integer类的类对象。还有另一种方法,如下面的语句:
Class c = Integer.class;
或者
Class c = Integer.TYPE;
它们可获得基本类型的类信息。其中后一种方法中访问的是基本类型的封装类 (如 Integer) 中预先定义好的 TYPE 字段。
第二步是调用诸如 getDeclaredMethods 的方法,以取得该类中定义的所有方法的列表。
一旦取得这个信息,就可以进行第三步了。
第三步是使用 reflection API 来操作这些信息,如下面这段代码:
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());
它将以文本方式打印出 String 中定义的第一个方法的原型。
反射经常由框架型代码使用,由于这一点,我们可能希望框架能够全面接入代码,无需考虑常规的接入限制。例如当代码在不值得信任的代码共享的环境中运行时。
假设有以下这个类的声明:
class DemoReflection
{
private String name = null;
private void doPrint(String s) {
System.out.println("print....."+s);
}
};
可以肯定的是,这个类中的属性name和方法doPrint都是无法对外展示的,但是使用了反射以后就可以办到。
package com.glsc.xu.search;
import java.lang.reflect.Method;
public class TestReflection {
public static void main(String args[]) {
try {
// 通过反映射技术得到DemoReflection的类型
Class cls = Class.forName("com.test.DemoReflection");
// 动态创建DemoReflection类的实力
Object instance = cls.newInstance();
// 通过反映射技术得到DemoReflection的非公有方法doPrint
Method m = cls.getDeclaredMethod("doPrint",
new Class[] { String.class });
// 表示可以随意访问该类中的方法
m.setAccessible(true);
// 调用doPrint方法
String s="hello world";
m.invoke(instance, new Object[] { s });
} catch (Exception ex) {
System.out.println(ex);
}
}
}
在该代码中,读者可能看到了一个比较陌生的方法setAccessible,这个方法非常重要,如果它不被设置成true那么所有非公有方法仍然无法调用,所以在调用非公有方法的时候需要注意这点。