java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象的功能称为java语言的反射机制。
下面写一个反射相关的例子,来体现这个性质:
我们首先创建一个方法,然后在这个方法里面,设计两个有参的方法,一个是public修饰的,一个是private修饰的。
public class Robot {
private String name;
public void sayHi(String helloSentence) {
System.out.println(helloSentence + "" + name);
}
private String throwHello(String tag) {
return "hello" + "" + tag;
}
}
现在倘若我们,创建一个新的class,将可以直接调用到sayHi方法,因为这个方法被public修饰,但是我们肯定无法调用到throwHello方法,因为是私有的,请看下图:
但是现在,我们将通过反射的方法,将私有的方法调用:
public class ReflectSample {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class rc = Class.forName("reflect.Robot");
//参数是我们要反射的类的相对路径,通过参数,来获取到类
Robot robot = (Robot) rc.newInstance();
//利用newInstance,我们可以获得到这个类的一个实例
System.out.println("Class name is" + rc.getName());
//获取到实例,自然就能得到类名了
robot.sayHi("Bob");
//这时候,我们可以很自然的调用public修饰的方法
Method getHello = rc.getDeclaredMethod("throwHello", String.class);
//通过类名和接收的参数或得到这个类的某个任意的方法
getHello.setAccessible(true);
//因为我们要获取到的方法是私有的,所以需要设置setAccessible
Object bob = getHello.invoke(robot, "Bob");
//获取到方法后,使用invoke进行手动填写参数,然后会通过刚刚Method创建的实例自动调用对应的方法
System.out.println(bob);
}
}
上面编写的方法中,核心的反射的api是getDeclaredMethod,我们可以通过这个方法获取到任意的方法,不管是不是私有的,如果这个方法是public,我们就可以直接用getMethod来获取,这其实都好说,就是换一个api,但是如果我们想获取到这个方法内部的参数,该怎么做呢?
可以参考如下一整套的代码;