# java 反射原理
动态代理:

【


如何为 java 对象创建一个代理对象?
java.lang.reflect.Proxy 类:提供了为对象产生代理对象的方法
| public static Object newProxyInstance(ClasLoader loader, Class<?>[] interfaces, InvocationHandler h) | |
| 参数一:用于指定用哪个类加载器,去加载生成的代理类 | |
| 参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法 | |
| 参数三:用来指定生成的代理对象要干什么事情 | 

反射就是能够获取到一个类的全部信息

获取 class 对象:
| Class.forName("全类名"); //--------- 全类名: 包名 + 类名 | |
| 类名.class | |
| 对象.getclass(); | 
三个阶段:
第一个阶段:

使用的是 Class.forName ("全类名"); 获取字节码文件,这是未写入内存

用的是类名.class

用的是对象.getclass ();
获取 class 对象后才能获取构造的方法

| /* | |
| Class 类中用于获取构造方法的方法 | |
| Constructor<?>[] getConstructors () ------ 公共函数的数组 | |
| Constructor<?>[] getDeclaredConstructors () ------ 所有函数的数组 | |
| Constructor<T> getConstructor (Class<?>... parameterTypes) ----- 返回单个公共构造方法对象 | |
| Constructor<T> getDeclaredConstructor (Class<?>... parameterTypes) ----- 返回翻个构造方法的对象 | |
| Constructor 类中用于创建对象的方法 | |
| T newInstance (odject... initargs) | |
| setAccessible (boolean flag) | |
| */ | |
|         //1. 获取 class 字节码文件对象 | |
| Class clazz= Class.forName("MyReflect2.Student"); | |
|         //2. 获取构造方法 | |
|         /*Constructor[] cons =clazz.getConstructors(); | |
|         for (Constructor c:cons){ | |
| System.out.println(c); | |
| } | |
| Constructor[] con1=clazz.getDeclaredConstructors(); | |
|         for (Constructor c:con1){ | |
| System.out.println(c); | |
| }*/ | |
|         // 获取名字 | |
| //        Constructor con2=clazz.getConstructor(String.class); | |
| //        System.out.println(con2); | |
| //        Constructor con3=clazz.getDeclaredConstructor(int.class); | |
| //        System.out.println(con3); | |
| //        Constructor con4=clazz.getDeclaredConstructor(String.class,int.class); | |
| //        System.out.println(con4); | |
| Constructor con46=clazz.getDeclaredConstructor(String.class,int.class); | |
|         // 获取修饰符 | |
| int modifiers = con46.getModifiers(); | |
| System.out.println(modifiers); | |
|        // 获取形参列表 | |
| Parameter[] parameters= con46.getParameters(); | |
| for (Parameter p:parameters) | |
|        { | |
| System.out.println(p); | |
|        } | |
|         // 暴力反射:临时取消权限的校验 | |
| //        con4.setAccessible(true); | |
| //        // 创建对象 | |
| //        Student stu = (Student) con46.newInstance("zhangsan",23); | |
| //        System.out.println(stu); | 
利用反射获取成员变量

| package MyReflect3; | |
| import java.lang.reflect.Field; | |
| public class MyReflectDemo { | |
| public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { | |
|         /* | |
| *Class 类中用于获取成员变量的方法 | |
| * Field [] getFields (): 返回所有公共成员变量对象的数组 | |
| * Field [] getDeclaredFields (): 返回所有成员变量对象的数组 | |
| * Field getField (String name): 返回单个公共成员变量对象 | |
| * Field getDeclaredField (String name): 返回单个成员变量对象 | |
| * | |
| * Field 类中用于创建对象的方法 | |
| * void set (Object obj ,Object value): 赋值 | |
| * Object get (Object obj) 获取值 | |
| * | |
| */ | |
|          //1. 获取 class 字节码文件的对象 | |
| Class clazz=Class.forName("MyReflect3.Student"); | |
|         //2. 获取所有的成员变量 | |
| Field[] fields=clazz.getDeclaredFields(); | |
| for (Field f:fields){ | |
| System.out.println(f); | |
|         } | |
|         // 获取单个的成员变量 | |
| Field gender = clazz.getDeclaredField("name"); | |
| System.out.println(gender); | |
|         // 获取权限修饰符 | |
| int zhuangtai =gender.getModifiers(); | |
| System.out.println(zhuangtai); | |
|         // 获取成员变量的名字 | |
| String n = gender.getName(); | |
| System.out.println(n); | |
|         // 获取数据类型 | |
| Class type = gender.getType(); | |
| System.out.println(type); | |
|         // 获取成员变量记录的值; | |
| Student s = new Student("zhangsan",23,"nan"); | |
| gender.setAccessible(true); | |
| Object value = gender.get(s); | |
| System.out.println(value); | |
|         // 修改对象里面记录的值 | |
| gender.set(s,"lisi"); | |
| System.out.println(s); | |
|     } | |
| } | 
利用反射获取成员方法:

| package MyReflect4; | |
| import java.lang.reflect.InvocationTargetException; | |
| import java.lang.reflect.Method; | |
| public class MyReflectDemo { | |
| public static void main(String [] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { | |
|         /* | |
| * Class 类中用于获取成员方法的方法 | |
| * Method [] getMethods (): 返回所有公共成员方法对象的数组,包括继承的 | |
| * Method0 getDeclaredMethods (): 返回所有成员方法对象的数组,不包括继承的 | |
| * Method getMethod (String name,Class<?>.parameterTypes): 返回单个公共成员方法对象 | |
| * Method getDeclaredMethod (String name,Class<?>parameterTypes): 返回单个成员方法对象 | |
| * Method 类中用于创建对象的方法 | |
| * Object invoke (Object obj,,Object..args): 运行方法 | |
| * 参数一:用 obj 对象调用该方法 | |
| * 参数二:调用方法的传递的参数(如果没有就不写) | |
| * 返回值:方法的返回值(如果没有就不写) | |
| * | |
| * 获取方法的修饰符 | |
| * 获取方法的名字 | |
| * 获取方法的形参 | |
| * 获取方法的返回值 | |
| * 获取方法的抛出的异常 | |
| * | |
| */ | |
|         //1. 获取 class 字节码文件对象 | |
| Class clazz = Class.forName("MyReflect4.Student"); | |
|         //2. 获取里面的所有方法对象 (包含符类中所有的父类方法) | |
|         /*Method[] methods=clazz.getMethods(); | |
|         for (Method m:methods){ | |
| System.out.println(m); | |
| }*/ | |
|         //2,获取里面的所有的方法(不能获取符父类的,可以获取本类中的所有方法) | |
| Method[] methods1=clazz.getDeclaredMethods(); | |
| for (Method m:methods1){ | |
| System.out.println(m); | |
|         } | |
| Method m=clazz.getDeclaredMethod("eat", String.class); | |
| m.setAccessible(true); | |
| System.out.println(m); | |
|         // 获取方法的修饰符 | |
| int modifiers= m.getModifiers(); | |
| System.out.println(modifiers); | |
|         // 获取方法的名字 | |
| String name= m.getName(); | |
| System.out.println(name); | |
|         // 获取方法的形参 | |
| Class[] parameterTypes= m.getParameterTypes(); | |
| for (Class c:parameterTypes){ | |
| System.out.println(c); | |
|         } | |
|         // 获取方法的返回值 | |
| Class returnType= m.getReturnType(); | |
| System.out.println(returnType); | |
|         // 获取方法的抛出的异常 | |
| Class[] exceptionTypes= m.getExceptionTypes(); | |
| for (Class e:exceptionTypes){ | |
| System.out.println(e); | |
|         } | |
|         // 创建对象 | |
| Student s=new Student(); | |
| Object o=m.invoke(s,"apple");// 参数一 obj 是对象,参数二:调用方法的参数 | |
| System.out.println(o); | |
|     } | |
| } | 
| package MyReflect4; | |
| public class Student { | |
| private String name; | |
| private int age; | |
| public Student() { | |
|     } | |
| public Student(String name, int age) { | |
| this.name = name; | |
| this.age = age; | |
|     } | |
|     /** | |
| * 获取 | |
| * @return name | |
| */ | |
| public String getName() { | |
| return name; | |
|     } | |
|     /** | |
| * 设置 | |
| * @param name | |
| */ | |
| public void setName(String name) { | |
| this.name = name; | |
|     } | |
|     /** | |
| * 获取 | |
| * @return age | |
| */ | |
| public int getAge() { | |
| return age; | |
|     } | |
|     /** | |
| * 设置 | |
| * @param age | |
| */ | |
| public void setAge(int age) { | |
| this.age = age; | |
|     } | |
| public void sleep(){ | |
| System.out.println("睡觉"); | |
|     } | |
| private void eat(String something){ | |
| System.out.println("再吃"+something); | |
|     } | |
| private void eat(String something,int age){ | |
| System.out.println("再吃"+something); | |
|     } | |
| public String toString() { | |
| return "Student{name = " + name + ", age = " + age + "}"; | |
|     } | |
| } | 
