反射的作用( 越过泛型检查 和 可以使用反射保存所有对象的具体信息 )

news2024/9/22 15:33:28

1、绕过 编译阶段 为集合添加数据

  • 反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以 为集合存入其他任意类型的元素的
  • 泛型只是在编译阶段可以约束集合只能操作某种数据类型,在 编译成Class文件进入 运行阶段 的时候,其真实类型都是不带泛型的集合,泛型相当于被擦除了。
package com.csdn.d6_reflect_genericity;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class ReflectDemo {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //需求:反射实现泛型擦除后,加入其他类型的元素
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<Integer> list2 = new ArrayList<>();

        System.out.println(list1.getClass());//class java.util.ArrayList
        System.out.println(list2.getClass());//class java.util.ArrayList

        System.out.println(list1.getClass() == list2.getClass());//true

        System.out.println("===============================");

        ArrayList<Integer> list3 = new ArrayList<>();
        list3.add(23);
        list3.add(22);

        Class<? extends ArrayList> aClass = list3.getClass();

        Method add = aClass.getDeclaredMethod("add", Object.class);
        boolean rs = (boolean) add.invoke(list3, "反射");
        System.out.println(rs);//true

        System.out.println(list3);//[23, 22, 反射]

        ArrayList list4 = list3;
        list4.add("注解");
        list4.add(false);
        System.out.println(list3);//[23, 22, 反射, 注解, false]

    }
}

1.1、反射为何可以给约定了泛型的集合存入其他类型的元素?

  • 编译成Class文件进入运行阶段 的时候,泛型会自动擦除
  • 反射是作用在 运行时 的技术,此时已经不存在泛型了 。

 2、通用框架的底层原理

需求

  • 给定任意一个对象,在不清楚对象字段的情况下,可以把对象的字段名称和对应值存储到文件中去。

分析

  1. 定义一个 方法 ,可以接收任意类的对象
  2. 每次收到一个对象后,需要解析这个对象的 全部成员变量名称
  3. 这个对象可能是 任意 的,那么怎么样才可以知道这个对象的全部成员变量名称呢
  4. 使用 反射 获取对象的 Class类对象 ,然后获取全部成员变量信息
  5. 遍历成员变量信息,然后提取本成员变量在对象中的 具体值
  6. 存入成员变量名称和值到 文件 中去即可
package com.csdn.d7_reflect_framework;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
/**
 * 目标:提供一个通用框架,支持保存所有对象的具体信息。
 */
public class ReflectDemo {
    public static void main(String[] args) {
        Student student = new Student("反射", '男', 100, "JavaSE", "暴力访问");
        MybatisUtil.save(student);

        Teacher teacher = new Teacher("注解", '女', 10000);
        MybatisUtil.save(teacher);
    }
}

class MybatisUtil {
    public static void save(Object object) {
        try {
            try (PrintStream ps = new PrintStream(new FileOutputStream("reflect\\src\\main\\java\\com\\csdn\\d7_reflect_framework\\object.txt",true))) {
                //1、提取这个对象的全部成员变量:只能反射可以解决
                Class<?> aClass = object.getClass();
                ps.println("==============" + aClass.getSimpleName() + "================");

                //2、提取它的全部成员变量
                Field[] fields = aClass.getDeclaredFields();
                //3、获取成员变量的信息
                for (Field field : fields) {
                    String name = field.getName();
                    //提取本成员变量的object对象中的值(取值)
                    field.setAccessible(true);

                    String value = field.get(object) + "";

                    ps.println(name + "=" + value);

                }
            }
        } catch (IllegalAccessException | FileNotFoundException e) {
            throw new RuntimeException(e);
        }

    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Student {
    private String name;
    private char sex;
    private int age;
    private String className;
    private String hobby;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Teacher {
    private String name;
    private char sex;
    private double salary;
}

 

 3、反射的作用?

  • 可以在运行时得到一个 类的 全部成分 然后操作
  • 可以 破坏封装性(很突出)
  • 也可以 破坏泛型的约束性(很突出)
  • 更重要的用途是适合:做 Java 高级框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zebec Protocol 薪酬支付工具 WageLink 上线,掀新一轮薪酬支付浪潮

Zebec Protocol 正在从多个方面推动流支付的应用&#xff0c;除了作为一种全新的支付手段来对支付领域进行重塑外&#xff0c;其也在以流支付体系为基础&#xff0c;不断地向薪酬发放领域深度的拓展。 在今年早些时候&#xff0c;Zebec Protocol 通过美国投资机构 Payroll Grow…

【类和对象+this引用】

文章目录 面向对象与面向过程面向对象关注的是对象&#xff0c;用类描述这个对象如何定义类如何更改类名 类的实例化this引用总结 面向对象与面向过程 面向对象就是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。 面向过程好比传统的洗衣服方式&#x…

【RNA world】RNA的多功能性与早期生命进化

文章目录 RNARNA plays core functions in Central Dogma of BiologyrRNAsnRNA RNA worldReplication催化作用感知环境变化并作出响应 来自Manolis Kellis教授&#xff08;MIT计算生物学主任&#xff09;的课 油管链接&#xff1a;6.047/6.878 Lecture 7 - RNA folding, RNA wo…

[尚硅谷React笔记]——第5章 React 路由

目录&#xff1a; 对SPA应用的理解对路由的理解前端路由原理路由的基本使用路由组件与一般组件NavLink的使用封装NavLink组件Switch的使用解决样式丢失问题路由的模糊匹配与严格匹配Redirect的使用嵌套路由向路由组件传递params参数向路由组件传递search参数.向路由组件传递st…

【Docker从入门到入土 3】Docker镜像的创建方法

Part3 一、Docker镜像1.1 镜像的概念1.2 镜像结构的分层 二、Docker镜像的创建2.1 基于现有镜像创建2.1.1 创建思路2.1.2 举个例子 2.2 基于本地模板创建2.3 基于Dockerfile 创建 三、Dockerfile 详解3.1 Dockerfile 操作指令3.1.1 常用的操作指令3.1.2 CMD和ENTRYPOINT的区别…

【Java基础面试四十一】、说一说你对static关键字的理解

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说一说你对static关键字…

hdlbits系列verilog解答(异或非门)-08

文章目录 wire线网类型介绍一、问题描述二、verilog源码三、仿真结果 wire线网类型介绍 wire线网类型是verilog的一种数据类型&#xff0c;它是一种单向的物理连线。它可以是输入也可以是输出&#xff0c;它与reg寄存器数据类型不同&#xff0c;它不能存储数据&#xff0c;只能…

文件系统相关

文件系统部分的大纲要求&#xff1a; 文件系统的全局结构&#xff1a;文件系统在外存中的结构&#xff0c;文件系统在内存中的结构外存空闲空间管理办法虚拟文件系统文件系统挂载 一、文件系统的层次结构 可分为三个层次&#xff1a;最低层是对象及其属性&#xff0c;中间层…

物证管理系统|智物证DW-S404是一套成熟系统

系统背景 我司物证智能管理系统&#xff08;智物证DW-S404&#xff09;是一套成熟系统&#xff0c;依托互3D技术、RFID技术、数据库技术、AI、视频分析技术对物证进行统一管理、分析的信息化、智能化、规范化的系统。 物证是公安或者监狱处理案件的关键凭证&#xff0c;针对过…

3交换机的配置与使用

越来越发觉大学的教程是真好&#xff0c;虽然说深度可能不太够&#xff0c;但作为入门实在太好了。中国也有公开课&#xff0c;推荐中国大学MOOC&#xff0c;感谢网易有道与高教社。 最近特别累、活也特别多&#xff0c;所以学习的时间少了很多。但看到MOOC之后&#xff0c;又…

软件测试(六)自动化测试 Junit5

Junit5 selenium是自动化测试框架&#xff08;写自动化测试用例&#xff09;Junit单元测试框架&#xff08;管理写好的测试用例&#xff09; 注解&#xff1a;Test&#xff0c;Disable &#xff0c;BeforeAll&#xff0c;AfterAll&#xff0c;BeforeEach&#xff0c;AfteEach…

操作系统——多个类别产品的生产者-消费者问题(王道视频p33、课本ch6)

1.问题解剖——得到的是 1个“互斥信号量” 3个“同步信号量” 其中特别注意&#xff0c;对于盘子plate可以清空的设计4个对象的&#xff0c;但是只用这一个同步信号量就可以实现 2.代码—— 3.由于这里的同步信号量的初值都是1&#xff0c;所以&#xff0c;即使不设置互斥信…

04.Finetune vs. Prompt

目录 语言模型回顾大模型的两种路线专才通才二者的比较 专才养成记通才养成记Instruction LearningIn-context Learning 自动Prompt 部分截图来自原课程视频《2023李宏毅最新生成式AI教程》&#xff0c;B站自行搜索 语言模型回顾 GPT&#xff1a;文字接龙 How are __. Bert&a…

大语言模型(LLM)综述(二):开发大语言模型的公开可用资源

A Survey of Large Language Models 前言3. RESOURCES OF LLMS3.1 公开可用的模型CheckPoints或 API3.2 常用语料库3.3 库资源 前言 随着人工智能和机器学习领域的迅速发展&#xff0c;语言模型已经从简单的词袋模型&#xff08;Bag-of-Words&#xff09;和N-gram模型演变为更…

RK3568 USB驱动开发

一.USB的DTS配置说明 1.USB 2.0 控制器 DTS 1.1 USB 2.0 Host 控制器 DTS USB 2.0 Host0 控制器 (EHCI & OHCI) 的DTS为例&#xff1a; 其中&#xff0c;EHCI 控制器的 compatible 固定为 “generic-ehci”&#xff0c;OHCI 控制器的 compatible 固定为 “genericohci”…

39.克鲁斯卡尔(Kruskal)算法

一言 已知n个顶点&#xff0c;选n-1条最短的边&#xff0c;不可成环。 概述 克鲁斯卡尔&#xff08;Kruskal&#xff09;算法是用来求加权连通图的最小生成树的算法。其基本思想是按照权值从小到大的顺序选择n-1条边&#xff0c;保证这n-1条边不构成回路。 这就要求要首先构…

写给Java/Android开发者的Python入门教程

1. 前言 对于Java/Android开发工程师来说&#xff0c;已经掌握了Java语言&#xff0c;这时再学其他语言(C/C除外)&#xff0c;都是比较容易的&#xff0c;可能花上几个小时就能入门了。 作为一个Android开发工程师&#xff0c;今天一时兴起&#xff0c;学了下Python&#xff0…

初识进程以及父子进程

一 进程概念 什么是进程呢&#xff1f;许多资料都说一个已经加载到内存的程序就叫进程&#xff0c;意思是只要代码到了内存就能跑起来了吗?接下来我就谈谈对进程概念的理解。 1 如何管理进程 我们可能运行多个进程&#xff0c;这些进程有些结束&#xff0c;有些要退出&#x…

yolov5自己的数据集制作

文章目录 一、制作数据集1、创建文件夹结构如下2、将之前的图片以及标注数据放入mydata文件夹3、新建一个mydata.yaml文件 二、基于数据集训练模型1、基于数据集训练模型2、开始根据制作好的数据集训练模型3、模型训练结束 三、部署模型 文章参考博主&#xff1a;风吹落叶花飘荡…