反射机制的功能极其强大,反射机制可以用来:
1. 在运行中分析类的能力
2. 在运行中查看对象,例如,编写一个toString方法供所有类使用
3. 实现通用的数组操作代码
4. 利用Method对象,这个对象很像C++中的函数指针
实际上,反射机制的默认行为受限于Java的访问控制。然而,如果一个Java程序没有收到安全管理器的控制,就可以覆盖访问控制。
为了达到这个目的,需要对用Field、Method、或Constructor对象的setAccessible方法,对public,甚至private访问权限的进行访问。
当然也可以访问到类中的域、构造方法、方法等,以java.lang.Integer类为例,利用反射机制对其进行访问:
public class ClassReflectionTest {
public static void printClass(Class cl) { //得到类的相关信息
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
String name = cl.getName();
System.out.print("class " + name);
Class supercl = cl.getSuperclass();
if (supercl != null && supercl != Object.class)
System.out.print(" extends" + supercl.getName());
System.out.println(" {");
}
public static void printConstructors(Class cl) { //得到构造器的相关信息
Constructor[] constructors = cl.getConstructors();
for (Constructor c : constructors) {
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(name + "(");
Class[] paramTypes = c.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
System.out.println();
}
public static void printMethods(Class cl) { //得到方法的相关信息
Method[] methods = cl.getMethods();
for (Method m : methods) {
System.out.print(" ");
String modifiers = Modifier.toString(m.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
Class type = m.getReturnType();
System.out.print(type + " (");
Class[] paramTypes = m.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(paramTypes[i].getName());
}
System.out.println(");");
}
String s = "quit";
s.charAt(0);
System.out.println();
}
public static void printFileds(Class cl) { //得到属性的相关信息
Field[] fields = cl.getDeclaredFields(); //getDelecaredFileds方法可以反射出private得所有属性
for (Field f : fields) {
String modifiers = Modifier.toString(f.getModifiers());
System.out.print(" ");
if (modifiers.length() > 0) System.out.print(modifiers + " ");
Class type = f.getType();
String name = f.getName();
System.out.println(type.getName() + " " + name);
}
System.out.println("}");
}
public static void main(String[] args) {
try {
Class cl = Class.forName("java.lang.Integer");
printClass(cl);
printConstructors(cl);
printMethods(cl);
printFileds(cl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
得到的结果:
public final class java.lang.Integer extendsjava.lang.Number {
public java.lang.Integer(int);
public java.lang.Integer(java.lang.String);
public static int (int);
public static int (int);
public static int (int);
public boolean (java.lang.Object);
public class java.lang.String ();
public static class java.lang.String (int, int);
public static class java.lang.String (int);
public int ();
public static int (int);
public volatile int (java.lang.Object);
public int (java.lang.Integer);
public byte ();
public short ();
public int ();
public long ();
public float ();
public double ();
public static class java.lang.Integer (int);
public static class java.lang.Integer (java.lang.String);
public static class java.lang.Integer (java.lang.String, int);
public static class java.lang.String (int);
public static class java.lang.Integer (java.lang.String);
public static int (int, int);
public static int (int);
public static int (java.lang.String);
public static int (java.lang.String, int);
public static class java.lang.String (int);
public static class java.lang.String (int);
public static class java.lang.Integer (java.lang.String);
public static class java.lang.Integer (java.lang.String, int);
public static class java.lang.Integer (java.lang.String, java.lang.Integer);
public static int (int);
public static int (int);
public static int (int, int);
public static int (int, int);
public static int (int);
public final void (long, int);
public final native void (long);
public final void ();
public final native class java.lang.Class ();
public final native void ();
public final native void ();
public static final int MIN_VALUE
public static final int MAX_VALUE
public static final java.lang.Class TYPE
static final [C digits
static final [C DigitTens
static final [C DigitOnes
static final [I sizeTable
private final int value
public static final int SIZE
private static final long serialVersionUID
static final boolean $assertionsDisabled
}