# java 反射原理

动态代理:

image-20241114213414206

image-20241114213902826

image-20241114221141977

如何为 java 对象创建一个代理对象?

java.lang.reflect.Proxy 类:提供了为对象产生代理对象的方法

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

image-20241124153154267

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

image-20241124153315026

获取 class 对象:

Class.forName("全类名");  //--------- 全类名: 包名 + 类名
类名.class
对象.getclass();

三个阶段:
第一个阶段:

image-20241124153624672

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

image-20241124153814310

用的是类名.class

image-20241124153836265

用的是对象.getclass ();

获取 class 对象后才能获取构造的方法

image-20241124162012345

/*
          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);

利用反射获取成员变量

image-20241124223524736

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);
    }
}

利用反射获取成员方法:

image-20241125210102701

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 + "}";
    }
}
Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

odiws WeChat Pay

WeChat Pay

odiws Alipay

Alipay

odiws PayPal

PayPal