java_反射

什么叫反射机制

1、反射机制允许程序员在执行期间借助于Reflection API 取得任何类的内部消息(比如成员变量,构造器,车成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到
2、加载完类之后,在堆中就会产生一个Class类型的对象(一个类只有一个Class对象),这个对象包含l类的完成结构信息,通过这个对象得到类的结构,这个class对象就像一面镜子,透过这个镜子看到类的结构,所有称之为反射

反射机制原理示意图

在这里插入图片描述

反射相关的主要类

在这里插入图片描述

反射的优点和缺点

在这里插入图片描述

反射调优
setAccessible 爆破执行 当不能访问私有的话 可以使用这个暴力执行
在这里插入图片描述

Class 类

一、基本介绍
在这里插入图片描述
Class 常用的api

package com.Class_demo;

import java.lang.reflect.Field;

/**
 * @author ZhouHao
 * @version 1.0
 * 成为想成为的人
 */
//class 类常用的方法
public class class_method_01 {
    public static void main(String[] args) throws Exception {
        //1 . 获取到 Car 类 对应的 Class 对象
        Class<?> cls = Class.forName("com.Class_demo.Car");
        //2. 输出 cls   获取实例
        System.out.println(cls);
        System.out.println("运行类型是:"+cls.getClass());
        //3. 得到包名
        System.out.println(cls.getPackage().getName());
        //4. 得到全类名
        System.out.println(cls.getName());
        //5. 通过 cls 创建对象实例
        Object o = cls.newInstance();
        //6. 通过反射获取属性 brand
        Field brand = cls.getField("brand");
        //7. 通过反射给属性赋值
        brand.set(o, "奔驰");
        System.out.println(brand.get(o));
        //8 我希望大家可以得到所有的属性(字段)
        Field[] fields = cls.getFields();
        for (Field f:fields){
            System.out.println(f.getName());
        }
    }
}

六种获取Class对象的方法

package com.Class_demo;

/**
 * @author ZhouHao
 * @version 1.0
 * 成为想成为的人
 */
//获取class的六种方式
public class get_class {
    public static void main(String[] args) throws Exception {
        //1. Class.forName
        Class<?> cls1 = Class.forName("com.Class_demo.Car");
        //2. 类名.class , 应用场景: 用于参数传递
        Class<Car> cls2 = Car.class;
        //3. 对象.getClass(), 应用场景,有对象实例
        Car car = new Car();
        Class<? extends Car> cls3 = car.getClass();
        //4. 通过类加载器【4 种】来获取到类的 Class 对象
        //(1)先得到类加载器 car
        ClassLoader classLoader = car.getClass().getClassLoader();
        //(2)通过类加载器得到 Class 对象
        Class<?> cls4 = classLoader.loadClass("com.Class_demo.Car");

        System.out.println(cls1.hashCode());
        System.out.println(cls2.hashCode());
        System.out.println(cls3.hashCode());
        System.out.println(cls4.hashCode());

        //5. 基本数据(int, char,boolean,float,double,byte,long,short)
        // 按如下方式得到 Class 类对象
        Class<Integer> cls5 = int.class;
//        Class<Double> cls6 = double.class;

        //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到 Class 类对象
        Class<Integer> cls6 = Integer.TYPE;

        System.out.println(cls5.hashCode());
        System.out.println(cls6.hashCode());
    }
}

类加载

基本说明
在这里插入图片描述
在这里插入图片描述

类加载过程图

在这里插入图片描述

一、加载阶段 解释
在这里插入图片描述
二、连接验证 解释
在这里插入图片描述
三、连接准备 解释
在这里插入图片描述
四、连接解析 解释
在这里插入图片描述
五、初始化 解释
在这里插入图片描述

通过反射获取类的结构信息 api

package com.get_struct_info;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author ZhouHao
 * @version 1.0
 * 成为想成为的人
 */
//通过反射来获取结构信息
public class test_demo {
    public static void main(String[] args) {

    }
    @Test
    public void  api_01() throws Exception {
        Class<?> cls = Class.forName("com.get_struct_info.person");

        //getName:获取全类名
        System.out.println("全类名:"+cls.getName());
        //getSimpleName:获取简单类名
        System.out.println("简单类名:"+cls.getSimpleName());
        //getFields:获取所有 public 修饰的属性,包含本类以及父类的
        Field[] fields = cls.getFields();
        System.out.println("本类及父类所有public属性:"+fields);
        //getDeclaredFields:获取本类中所有属性
        Field[] declaredFields = cls.getDeclaredFields();
        System.out.println("本类所有属性:"+declaredFields);
        //getMethods:获取所有 public 修饰的方法,包含本类以及父类的
        Method[] methods = cls.getMethods();
        System.out.println("本类及父类所有public方法:"+methods);
        //getDeclaredMethods:获取本类中所有方法
        Method[] declaredMethods = cls.getDeclaredMethods();
        System.out.println("本类所有方法:"+declaredMethods);
        //getConstructors: 获取所有 public 修饰的构造器,包含本类
        Constructor<?> constructor = cls.getConstructor();
        System.out.println("本类及父类所有public构造器:"+constructor);
        //getDeclaredConstructors:获取本类中所有构造器
        Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
        System.out.println("本类所有的构造器:"+declaredConstructors);
        //getPackage:以 Package 形式返回 包信息
        System.out.println("返回包的信息:"+cls.getPackage());
        //getSuperClass:以 Class 形式返回父类信息
        System.out.println("返回父类信息:"+cls.getSuperclass());
        //getInterfaces:以 Class[]形式返回接口信息
        Class<?>[] interfaces = cls.getInterfaces();
        System.out.println("返回接口信息:"+interfaces);
        //getAnnotations:以 Annotation[] 形式返回注解信息
        Annotation[] annotations = cls.getAnnotations();
        System.out.println("返回注解信息:"+annotations);

    }
    @Test
        public void api_02() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.get_struct_info.person");
            //        以 int的形式返回修饰符
            /**默认修饰符 0,public 1, private 2, protected 4, static 8,
             *  final 16   eg: public(1)+static(8)=9  */
            Field[] declaredFields = cls.getDeclaredFields();
            for(Field f:declaredFields){
                System.out.println("属性名:"+f.getName()+
                            "属性的修饰符:"+f.getModifiers()+
                            "属性的类型:"+f.getType());
            }

        }
    @Test
    public void api_03() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.get_struct_info.person");
        Method[] methods = cls.getDeclaredMethods();
        for (Method m:methods){
            System.out.println("方法名:"+m.getName()+
                            "方法的修饰符:"+m.getModifiers()+
                            "返回类型:"+m.getReturnType()+
                            "返回参数的数组:"+m.getParameterTypes());
        }
    }
    @Test
    public void api_04() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.get_struct_info.person");
        Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
        for (Constructor c:declaredConstructors){
            System.out.println("构造器名:"+c.getName()+
                            "构造器的修饰符:"+c.getModifiers()+
                            "构造器的参数de数组:"+c.getParameterTypes());
        }


    }
}

通过反射创建对象实例api

package com.create_new;

import sun.swing.plaf.windows.ClassicSortArrowIcon;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author ZhouHao
 * @version 1.0
 * 成为想成为的人
 */
//通过class 创建对象实列
public class create_eg {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> cls = Class.forName("com.create_new.user");
        //1. 通过 public 的无参构造器创建实例
        Object o = cls.newInstance();
        System.out.println(o);
        //2. 通过 public 的有参构造器创建实例
        Constructor<?> constructor = cls.getConstructor(String.class);
        Object o1 = constructor.newInstance("小浩纸");
        System.out.println(o1);
        //3. 通过非 public 的有参构造器创建实例
        Constructor<?> constructor1 = cls.getDeclaredConstructor(String.class, int.class);
//        访问私有的会报错  需要爆破
        constructor1.setAccessible(true);
        Object o2 = constructor1.newInstance("小浩纸~~", 19);
        System.out.println(o2);
    }
}

通过反射访问类中成员api

package com.反射访问成员;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author ZhouHao
 * @version 1.0
 * 成为想成为的人
 */
public class demo {
    public static void main(String[] args)  {
    }
//    演示反射来访问成员属性
    @Test
    public void demo_01()throws Exception{
        Class<?> cls = Class.forName("com.反射访问成员.student");
        Object o = cls.newInstance();

//        1.获取public属性
        Field age = cls.getField("age");
//        给属性设置值
        age.set(o, 19);
        System.out.println(o);

//        2.操作private 私有的属性
        Field name = cls.getDeclaredField("name");
//        私有的话要进行爆破
        name.setAccessible(true);
        name.set(o,"小浩纸");
//        如果是static 的 o ---> null 可以置空
        name.set(null, "小浩纸~");
        name.get(null);
        System.out.println(o);
    }
//---------------------------------------------------------
//      通过反射来访问方法
    @Test
    public void demo_02()throws Exception{
        Class<?> cls = Class.forName("com.反射访问成员.student");
        Object o = cls.newInstance();
//        1.访问public方法
        Method hi = cls.getMethod("hi", String.class);
        hi.invoke(o, "小浩纸~");

//        2.调用私有private方法
        Method say = cls.getDeclaredMethod("say", int.class, String.class, char.class);
//        以为私有的  爆破
        say.setAccessible(true);
//        因为是static 可以置空
        System.out.println(say.invoke(null, 10,"小浩",'男'));
        System.out.println(say.invoke(o, 10,"小浩",'男'));
//      在反射中,如果方法有返回值,统一返回 Object ,
//      但是他运行类型和方法定义的返回类型一致
        Object invoke = say.invoke(null, 10, "小浩", '男');
        System.out.println("运行类型是:"+invoke.getClass()); //String


    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有心肝,只有干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值