一、什么是反射
反射首先是能够获取到Java中的反射类的字节码,然后将字节码中的方法,变量,构造函数等映射成 相应的 Method、Filed、Constructor 等类
二、反射的API
获取class字节码对象 的3 种方法
//第一种Class studentClass = Student.class; //第二种Student student = new Student();Class studentClass1 = student.getClass();//第三种 必须为全路径 Class studentClass2 = Class.forName("com.example.service.Impl.Student");
常用的一些API
获取包名 类名clazz.getPackage().getName()//包名clazz.getSimpleName()//类名clazz.getName()//完整类名获取成员变量定义信息getFields()//获取所有公开的成员变量,包括继承变量getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量getField(变量名)getDeclaredField(变量名)获取构造方法定义信息getConstructor(参数类型列表)//获取公开的构造方法getConstructors()//获取所有的公开的构造方法getDeclaredConstructors()//获取所有的构造方法,包括私有getDeclaredConstructor(int.class,String.class)获取方法定义信息getMethods()//获取所有可见的方法,包括继承的方法getMethod(方法名,参数类型列表)getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法getDeclaredMethod(方法名,int.class,String.class)反射新建实例clazz.newInstance();//执行无参构造创建对象clazz.newInstance(666,”海绵宝宝”);//执行含参构造创建对象clazz.getConstructor(int.class,String.class)//获取构造方法反射调用成员变量clazz.getDeclaredField(变量名);//获取变量clazz.setAccessible(true);//使私有成员允许访问f.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给nullf.get(实例);//访问指定实例变量的值,静态变量,第一参数给null反射调用成员方法Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);m.setAccessible(true);//使私有方法允许被调用m.invoke(实例,参数数据);//让指定实例来执行该方法
三、示例
首先定义一个类
@Data@Builder@Servicepublic class Student {public String name;private int age;public char egx;protected Integer phone;Student(String name ,int age,char egx,Integer phone){System.out.println("默认的构造方法");}public Student(){System.out.println("调用无参构造方法。。。。。");}publicStudent(String name){this.name = name;System.out.println("name:"+name);}public Student(String name,int age){System.out.println("name:"+name+","+"age:"+age);}private Student(int age){System.out.println("私有的构造方法");}protected Student(boolean b){System.out.println("受保护的构造方法");}public String get(){return "调用方法";}public String getMethod(String string){return string + "是个大学老师!";}}
获取构造方法
/* * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员; * * 1.获取构造方法: * 1).批量的方法: * public Constructor[] getConstructors():所有"公有的"构造方法public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有) * 2).获取单个的方法,并调用: * public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法: * public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有; * * 调用构造方法: * Constructor-->newInstance(Object... initargs) */System.out.println("==================调用构造方法=====================");Class clazz = Student.class;//类路径System.out.println(clazz.getName());//获取所有的公共构造方法 Constructor[] constructors = clazz.getConstructors();for (Constructor constructor : constructors){System.out.println(constructor);}//获取所有的构造方法 包含私有的受保护的Constructor[] declaredConstructors = clazz.getDeclaredConstructors();for (Constructor constructor : declaredConstructors){System.out.println(constructor);}//获取 公共的参数为String的构造方法Constructor constructor = clazz.getConstructor(String.class);System.out.println(constructor);//获取公共的无参构造方法Constructor constructor1 = clazz.getConstructor(null);System.out.println(constructor1);Object o = constructor1.newInstance();Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);//暴力访问,忽略掉访问修饰符declaredConstructor.setAccessible(true);Object object = declaredConstructor.newInstance("男");
获取成员变量并调用:
/* * 获取成员变量并调用: * * 1.批量的 * 1).Field[] getFields():获取所有的"公有字段" * 2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有; * 2.获取单个的: * 1).public Field getField(String fieldName):获取某个"公有的"字段; * 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的) * *设置字段的值: * Field --> public void set(Object obj,Object value): * 参数说明: * 1.obj:要设置的字段所在的对象; * 2.value:要为字段设置的值; * */System.out.println("=====================获取字段参数=====================");Class clazz = Class.forName("com.example.service.Impl.Student");;//获取所有公共参数Field[] fields = clazz.getFields();for(Field field : fields){// System.out.println(field);}//获取所有参数Field[] declaredFields = clazz.getDeclaredFields();for (Field field : declaredFields){System.out.println(field);}//获取 name 参数Field name = clazz.getField("name");// Student s = new Student();Object o = clazz.getConstructor(null).newInstance();//给name 参数 赋值name.set(o,"黄磊");Student s = (Student)o;System.out.println("验证名字:"+s.getName());//获取私有参数Field phone = clazz.getDeclaredField("phone");//暴力访问,忽略掉访问修饰符phone.setAccessible(true);//第一个参数为设置的对象,第二个参数为要传入的实参//等同与student.setPhone(12356789)phone.set(o,123456789);System.out.println("验证电话:"+s.getPhone());
获取方法并调用
System.out.println("=====================获取方法=======================");Class clazz = Student.class;//获取所有公共的方法Method[] methods = clazz.getMethods();//获取所以方法 包含私有的,受保护的Method[] declaredMethods = clazz.getDeclaredMethods();for (Method method : declaredMethods){System.out.println(method.getName());}Method getMethod = clazz.getMethod("getMethod",String.class);//无参初始化Object o1 = clazz.newInstance();//执行方法为私有的 得先设置私有可见getMethod.setAccessible(true);//传入参数,执行方法Object o = getMethod.invoke(o1,"ww");System.out.println(o.toString());