Java反射机制是在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
接下来举一个反射的例子:
创建一个实体类,包含两个有参方法,一个是public修饰一个是private修饰。
public class Person {
private String name;
public void satHello(String sentence){
System.out.println(sentence + " " + name);
}
private String hello(String flag){
return "Hello" + " " + flag;
}
}
在一个新的类中是可以调用到sayHello方法的,但是无法调用到hello方法,因为hello方法时私有的。
通过反射是可以调用到私有方法的:
public class PersonReflect {
public static void main(String[] args) throws ClassNotFoundException,
IllegalAccessException,
InstantiationException,
NoSuchMethodException,
InvocationTargetException {
//参数是累的相对路径,通过参数获取到类
Class dp = Class.forName("daily.Person");
//利用newInstance获得这个类的实例
Person person = (Person) dp.newInstance();
System.out.println("Class name is : " + dp.getName());
//可以调用的public修饰的方法
person.sayHello("LJY");
//通过类名和接收到的参数得到这个类任意的某个方法
Method sayHello = dp.getDeclaredMethod("hello", String.class);
//要调用的方法是私有的,需要将setAccessible设置为true
sayHello.setAccessible(true);
//使用invoke填写参数,通过Method创建的实例自动调用对应的方法
Object ljy = sayHello.invoke(person, "ljy");
System.out.println(ljy);
}
}
上面所示实例中,反射的API是getDeclaredMethod,可以通过这个API获取到任意的方法不管是私有的还是共有的。如果是public修饰的方法,可以直接使用getMethod,但是如果要是想要获取到这个方法内部的参数该如何操作???
完整的代码参考如下:
public class PersonReflect {
public static void main(String[] args) throws ClassNotFoundException,
IllegalAccessException,
InstantiationException,
NoSuchMethodException,
InvocationTargetException,
NoSuchFieldException {
//参数是累的相对路径,通过参数获取到类
Class dp = Class.forName("daily.Person");
//利用newInstance获得这个类的实例
Person person = (Person) dp.newInstance();
System.out.println("Class name is : " + dp.getName());
//可以调用的public修饰的方法
person.sayHello("LJY");
//通过类名和接收到的参数得到这个类任意的某个方法
Method hello = dp.getDeclaredMethod("hello", String.class);
//要调用的方法是私有的,需要用setAccessible设置为true
hello.setAccessible(true);
//使用invoke填写参数,通过Method创建的实例自动调用对应的方法
hello.invoke(person, "ljy");
Method sayHello = dp.getMethod("sayHello", String.class);
sayHello.invoke(person, "Hello");
//获取Person实体类中的属性
Field name = dp.getDeclaredField("name");
//属性是私用的需要用setAccessible设置为true
name.setAccessible(true);
name.set(person, "LJYLJY");
sayHello.invoke(person, "Hello");
}
}