Java 复习 01 注解和反射

1.1 注解和反射


以前 学习过 注解和 反射。但是 真的 没有 理解 它 能干嘛。

其实 注解和反射 更多的是 应用于 设计一个框架上。而且 反射 用到的最多!不要 一提到 反射 就想到 注解,一些 实战的 框架,在实现某些 功能的时候,都是直接用的 反射,并未与 注解连用。

那么为什么 要 与 注解联用呢,最主要的原因 在于 我们在使用框架的时候 更加方便。

  • 设计一个框架 设计技术点

反射机制、自定义注解、设计模式(23种)、AOP 技术(判断 目标是否应用了 自定义注解,然后再通过 反射获取,进行二次处理。)、netty技术(客户端和服务端 通讯)、spring 的架构设计原理(主要是为了 整合在 spring 中)、springboot 自定义插件、多线程 或 JUC 等等

  • 反射技术

使用反射机制 可以动态获取到 class 的信息,比如 方法的信息、方法的参数、属性 等等。

反射技术应用的场景

  1. JDBC 加载驱动连接 class.forname() 在这里插入图片描述

  2. Spring 容器框架 IOC 实例化对象

  3. 自定义注解 生效(反射 + AOP)
    当初学习的时候 为啥 说 没太了解 注解和反射 的联用呢,是因为 我们 只知道 注解是那样定义的,然后 能通过 反射拿到信息,但是这个 注解写了之后 有啥真实意义吗?好像又 没有。。。

  4. 第三方 核心的 框架 都会用到 反射技术的。

反射技术的 使用

  1. 反射技术 来 新建 对象
    在这里插入图片描述
Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");
aClss.newInstance();//它 会默认 走 无参构造,去 new 一个 对象。

在这里插入图片描述

  1. 如何知道 目标 应用了注解

在我们 获取了 目标后,是 可以通过 目标 来获取 注解的。如果能拿到 注解,就证明 该目标 应用了注解,那我们就可以 来进行 一些 操作了。

在这里插入图片描述


1.2 识别 注解 并用反射 实战

在这里插入图片描述

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;

public class 实战 {
    Class<?> C = null;
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IOException {
        Class<?> c = Class.forName("Student");

        实战 aop = new 实战(c);

    }

    public 实战(Class<?> C) throws IOException {
        this.C = C;
        Field[] fields = C.getDeclaredFields();

        System.out.println(fields);

        for(Field f:fields){
            f.setAccessible(true);// 开权限
            FileOutputStream file = new FileOutputStream("data.txt", true);
            Fieldmu Fmu = f.getAnnotation(Fieldmu.class);
            System.out.println(Fmu);
            if(Fmu != null){// 也就是 我们 有注解,那么我们 可以做 很多的操作
                String columnNameMu = Fmu.columnName();
                String typeMu = Fmu.type();
                int length = Fmu.length();
                String lemngthMu = String.valueOf(length);
                String ret = "["+f.getName() + "字段]\n" +"columnNameMu="+columnNameMu+"\n"+"type="+typeMu+"\n"
                        + "lemngth="+lemngthMu+"\n";
                file.write(ret.getBytes(StandardCharsets.UTF_8));
                System.out.println(f.getName() + ":处理完成!");
            }
        }

    }

}

在这里插入图片描述
简单的 打破 双亲委派,可以 动态的 加载类,然后 创建 Obj 对象。

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

public class 实战 {
    Class<?> C = null;
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        MyClassLoader myClassLoader = new MyClassLoader("C:\\Users\\muqua\\Desktop\\NotesANDLearn\\" +
                "JAVA复习\\注解和反射\\注解和反射\\out\\production\\注解和反射");
        Class<?> c = myClassLoader.findClass("Student");
        Method print = c.getDeclaredMethod("print");
        Object student = c.newInstance();
        System.out.println(student.getClass().getSimpleName());
        print.invoke(student);


        //实战 aop = new 实战(c);
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while(true){
            String msg = reader.readLine();
            if(msg.equals("重加载")){
                myClassLoader = new MyClassLoader("C:\\Users\\muqua\\Desktop\\NotesANDLearn\\" +
                        "JAVA复习\\注解和反射\\注解和反射\\out\\production\\注解和反射");
                c = myClassLoader.findClass("Student");
                print = c.getDeclaredMethod("print");
                student = c.newInstance();
                print.invoke(student);

                //s.print();
            }
        }

    }

    public 实战(Class<?> C) throws IOException {
        this.C = C;
        Field[] fields = C.getDeclaredFields();

        System.out.println(fields);

        for(Field f:fields){
            f.setAccessible(true);// 开权限
            FileOutputStream file = new FileOutputStream("data.txt", true);
            Fieldmu Fmu = f.getAnnotation(Fieldmu.class);
            System.out.println(Fmu);
            if(Fmu != null){// 也就是 我们 有注解,那么我们 可以做 很多的操作
                String columnNameMu = Fmu.columnName();
                String typeMu = Fmu.type();
                int length = Fmu.length();
                String lemngthMu = String.valueOf(length);
                String ret = "["+f.getName() + "字段]\n" +"columnNameMu="+columnNameMu+"\n"+"type="+typeMu+"\n"
                        + "lemngth="+lemngthMu+"\n";
                file.write(ret.getBytes(StandardCharsets.UTF_8));
                System.out.println(f.getName() + ":处理完成!");
            }
        }

    }

}

自定义 类加载器

import sun.misc.PerfCounter;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.ProtectionDomain;

/**
 * Created by IntelliJ IDEA
 * User: yqm02
 * Date: 2021/8/22
 * Time: 17:25
 */
public class MyClassLoader extends ClassLoader {
    /**
     *  加载器加载的路径
     *  */
    private String classPath;

    public MyClassLoader(String path) {
        this.classPath = path;
    }

    protected byte[] loadByte(String name) throws IOException {
        name = name.replaceAll("\\.", "/");
        String path = classPath + "/" + name + ".class";
        FileInputStream fileInputStream = new FileInputStream(path);
        int len = fileInputStream.available();
        byte[] data = new byte[len];
        fileInputStream.read(data);
        fileInputStream.close();
        return data;
    }

    @Override
    protected Class<?> findClass(String name) {
        byte[] data = null;
        try {
            data = loadByte(name);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return defineClass(name, data, 0, data.length);
    }
    
}

在这里插入图片描述

但现在 还有一个问题,就是 我不知道为什么 通过 类加载器 获取的 Class 对象 使用 newInstance() 方法 创建的 实例化对象 无法进行 强转 变为 Student

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值