栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 复习 01 注解和反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 复习 01 注解和反射

1.1 注解和反射

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

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

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

设计一个框架 设计技术点

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

反射技术

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

反射技术应用的场景

    JDBC 加载驱动连接 class.forname()

    Spring 容器框架 IOC 实例化对象

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

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

反射技术的 使用

    反射技术 来 新建 对象
Class aClass = Class.forName("com.mayikt.entity.UserEntity");
aClss.newInstance();//它 会默认 走 无参构造,去 new 一个 对象。

    如何知道 目标 应用了注解

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


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;


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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/711217.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号