1.反射之操作成员方法:
Method类概述
每一个成员方法都是一个Method对象
反射之操作成员方法的目的
操作Method对象来调用成员方法
使用:
1.如何通过反射获得类中的成员方法:Class类的方法
- public Method getMethod(String name, Class<?>... parameterTypes)
根据方法名称和参数类型获得对应的方法对象,只能获得public的
考虑到方法有重载,所以还需要加上可变参数作为形参来辨别具体是哪个方法要调用
- public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
根据方法名称和参数类型获得对应的方法对象,包括public、protected、默认、private
- public Method[] getDeclaredMethods()
获得类中的所有成员方法对象,返回数组,包括public、protected、默认、private
- public Method[] getMethods()
获得类中的所有成员方法对象,返回数组,只包括public
2.如何通过反射执行获取类中的成员方法:Method方法
- public Object invoke(Object obj, Object... args)
参数1:调用方法的对象
参数2:调用方法时传递的实参
返回值:执行的方法的返回值
- public void setAccessible(boolean flag)
设置“暴力访问”:是否取消权限检查,true是取消的意思,false是不取消
学生类
public class Student {
public void show1(){
System.out.println("show1 方法");
}
public void show2(int num){
System.out.println("show2 方法...num:"+num);
}
private void show3(){
System.out.println("show3 方法");
}
private void show4(String str){
System.out.println("show1 方法...:"+str);
}
public int show5(int num){
System.out.println("show1 方法...:"+num);
return 100;
}
}
测试类
// 获取Student的Class对象
Class<Student> c = Student.class;
/*
* 获取单个方法
* */
Method show1 = c.getMethod("show1");
System.out.println(show1);
Method show2 = c.getMethod("show2",int.class);
System.out.println(show2);
Method show3 = c.getDeclaredMethod("show3");
System.out.println(show3);
Method show4 = c.getDeclaredMethod("show4", String.class);
System.out.println(show4);
Method show5 = c.getDeclaredMethod("show5", int.class);
System.out.println(show5);
System.out.println("===============================");
/*
* 获取所有方法
* */
Method[] declaredMethods = c.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("=======================================");
// 通过反射创建Student对象
Student s = c.getDeclaredConstructor().newInstance();
// 通过反射执行show1表示的show1方法
show1.invoke(s);// s.show1();
// 通过反射执行show2表示的show2方法
show2.invoke(s,100);
// 通过反射执行show3表示的show3方法
show3.setAccessible(true);
show3.invoke(s);
// 通过反射执行show4表示的show4方法
show4.setAccessible(true);
show4.invoke(s,"张三");
// 通过反射执行show5表示的show5方法
Object invoke = show5.invoke(s, 10);
System.out.println(invoke);
}
}
2.需求:访问Student类中的成员,构造方法和成员方法
创建一个学生类
public class Student {
public String name ;
public int age ;
public void show1(){
System.out.println("show1 方法");
}
public void show2(int num){
System.out.println("show2 方法...num:"+num);
}
private void show3(){
System.out.println("show3 方法");
}
private void show4(String str){
System.out.println("show1 方法...:"+str);
}
public int show5(int num){
System.out.println("show1 方法...:"+num);
return 100;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student(String name) {
this.name = name;
}
private Student(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
// 第一步:获取该类的字节码对象
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
// 第一步:获取该类的字节码对象
Class<Student> c = Student.class;
// 第二部:获取所有的构造方法
Constructor<?>[] cons = c.getDeclaredConstructors();
Student student = c.getDeclaredConstructor().newInstance();
for (Constructor<?> con : cons) {
// System.out.println(con);
//System.out.println(con.getName());
//student = (Student) con.newInstance();
}
// 第三步:获取所有的成员方法
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
//System.out.println(method); 获取所有方法,有参还是无参数,都能获取到
if (method.getName().equals("show1")){
method.invoke(student);
}
if (method.getName().equals("show4")){
method.setAccessible(true);
method.invoke(student,"张三");
}
if (method.getName().equals("show5")){
Object invoke = method.invoke(student, 20);
method.invoke(invoke);
}
}
}
}
3.Field类概述
每一个成员变量都是一个Field类的对象
射值操作成员变量的目的
通过Field对象给对应的成员变量赋值和取值
使用:
1.如果通过反射获取类的成员变量:Class类的方法
- public Field getField(String name)
- public Field[] getFields() throws
- public Field getDeclaredField(String name)
- public Field[] getDeclaredFields()
2.如何通过反射访问获取的类的成员变量:Field类的方法
- public Class<?> getType():获取属性的类型,返回Class对象
- public void set(Object obj, Object value)
- public Object get(Object obj)
- public void setAccessible(boolean flag):暴力反射
学生类
public class Student {
public String name;
private int age;
public Student() {
}
public Student(String name) {
this.name = name;
}
public Student(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
public class Tests {
public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 获取Student类的Class对象
Class<Student> c = Student.class;
/*
* 获取单个成员变量*/
// 通过反射获取name成员变量
Field name = c.getField("name");
System.out.println(name);
// 通过反射获取age成员变量
Field age = c.getDeclaredField("age");
System.out.println(age);
System.out.println("============================");
/*
* 获取所有成员变量
* */
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("==============================");
// 通过反射获取Student对象
Student student = c.getDeclaredConstructor().newInstance();
//获取表示name属性的类型
Class<?> name1 = name.getType();
System.out.println(name1);
// 获取表示age属性的类型
Class<?> age2 = age.getType();
System.out.println(age2);
System.out.println("=================================");
//取消name或者age属性的权限检查
age.setAccessible(true);
//通过反射给name或者age属性赋值
name.set(student,"张三");
age.set(student,18);
System.out.println("==========================");
//通过反射获取name属性的值
System.out.println(name.get(student));
//通过反射获取age的属性的值
System.out.println(age.get(student));
}
}