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

本文主要是介绍反射的作用( 越过泛型检查 和 可以使用反射保存所有对象的具体信息 ),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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.ArrayListSystem.out.println(list2.getClass());//class java.util.ArrayListSystem.out.println(list1.getClass() == list2.getClass());//trueSystem.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);//trueSystem.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.chinasem.cn/article/279807

相关文章

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

Python虚拟环境终极(含PyCharm的使用教程)

《Python虚拟环境终极(含PyCharm的使用教程)》:本文主要介绍Python虚拟环境终极(含PyCharm的使用教程),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录一、为什么需要虚拟环境?二、虚拟环境创建方式对比三、命令行创建虚拟环境(venv)3.1 基础命令3