反射
通过Java的反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问,检测和修改描述Java对象本身信息的功能。通过反射可以访问构造方法,成员变量,和成员方法。
访问构造方法:Java反射——访问构造方法
访问成员变量:Java反射——访问成员变量
访问成员方法
利用Method对象可操纵相应的方法。
Method类提供的常用方法
方法 | 说明 |
---|---|
getName() | 获取该方法的名称 |
getParameterTypes() | 按照声明顺序以Class数组的形式获得该方法的各个参数的类型 |
getReturnType() | 以Class对象的形式获得该方法的返回值类型 |
getExceptionTypes() | 以Class数组的形式获得该方法可能抛出的异常类型 |
invoke(Object obj, Object … args) | 利用指定参数args执行指定对象obj中的该方法,返回值为Object型 |
isVarArgs() | 查看该构造方法是否允许带有可变数量的参数,如果允许返回true,不允许返回false |
getModifiers() | 获得可以解析出该方法所采用修饰符的整数 |
getModifiers()方法的返回值是所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以以字符串的形式获得所有修饰符。
Modifier类中的常用解析方法:
静态方法 | 说明 |
---|---|
isPublic(int mod) | 查看是否被public修饰符修饰,如果是返回true,反之返回false |
isProtected(int mod) | 查看是否被protected修饰符修饰,如果是返回true,反之返回false |
isPrivate(int mod) | 查看是否被private修饰符修饰,如果是返回true,反之返回false |
isStatic(int mod) | 查看是否被static修饰符修饰,如果是返回true,反之返回false |
isFinal(int mod) | 查看是否被Final修饰符修饰,如果是返回true,反之返回false |
toString(int mod) | 以字符串形式返回所有修饰符 |
写个例子,来反射一个类里有多少个方法,拿java.lang.String来举例子。
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("java.lang.String");// 创建class对象
Method ms[] = c.getDeclaredMethods();// 获得所有的方法
for (Method m : ms) {
System.out.print(Modifier.toString(m.getModifiers()) + " ");// 获取所有方法的修饰符
System.out.print(m.getReturnType().getSimpleName() + " ");// 获取方法的返回值类型
System.out.print(m.getName() + "(");// 获取方法的名字
Class cla1[] = m.getParameterTypes();// 获取方法的参数类型
for (int i = 0; i < cla1.length; i++) {
System.out.print(cla1[i].getSimpleName() + " args ");
}
System.out.print(")");
Class cla2[] = m.getExceptionTypes();// 获取方法可能抛出的异常
for (int i = 0; i < cla2.length; i++) {
System.out.print(cla2[i].getSimpleName());
}
System.out.println(" { }");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
输出了这个类中所有方法的修饰符,方法名,返回值类型,方法的参数以及方法可能抛出的异常。
知道了如何反射这些方法,要如何调用这些方法呢?在Study中创建一个简单的成员方法。
public class Study {
public void add(int a, int b) {
System.out.println("a+b="+(a+b));
}
}
计算a+b的值。在Study2中调用,计算。
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("study.czm.Study");// 创建class对象
Method ms[] = c.getDeclaredMethods();// 获得所有的方法
for (Method m : ms) {
System.out.print(Modifier.toString(m.getModifiers()) + " ");// 获取所有方法的修饰符
System.out.print(m.getReturnType().getSimpleName() + " ");// 获取方法的返回值类型
System.out.print(m.getName() + "(");// 获取方法的名字
Class cla1[] = m.getParameterTypes();// 获取方法的参数类型
for (int i = 0; i < cla1.length; i++) {
System.out.print(cla1[i].getSimpleName() + " args ");
}
System.out.print(")");
Class cla2[] = m.getExceptionTypes();// 获取方法可能抛出的异常
for (int i = 0; i < cla2.length; i++) {
System.out.print(cla2[i].getSimpleName());
}
System.out.println(" { }");
}
Constructor cs = c.getConstructor();// 创建实例化对象
Object obj = cs.newInstance();// 无参构造方法创建对象
Method m = c.getDeclaredMethod("add", int.class, int.class);// 创建方法对象
m.invoke(obj, 1, 2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}