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

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

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

相关文章

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

详解如何使用Python提取视频文件中的音频

《详解如何使用Python提取视频文件中的音频》在多媒体处理中,有时我们需要从视频文件中提取音频,本文为大家整理了几种使用Python编程语言提取视频文件中的音频的方法,大家可以根据需要进行选择... 目录引言代码部分方法扩展引言在多媒体处理中,有时我们需要从视频文件中提取音频,以便进一步处理或分析。本文

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

使用Dify访问mysql数据库详细代码示例

《使用Dify访问mysql数据库详细代码示例》:本文主要介绍使用Dify访问mysql数据库的相关资料,并详细讲解了如何在本地搭建数据库访问服务,使用ngrok暴露到公网,并创建知识库、数据库访... 1、在本地搭建数据库访问的服务,并使用ngrok暴露到公网。#sql_tools.pyfrom

使用mvn deploy命令上传jar包的实现

《使用mvndeploy命令上传jar包的实现》本文介绍了使用mvndeploy:deploy-file命令将本地仓库中的JAR包重新发布到Maven私服,文中通过示例代码介绍的非常详细,对大家的学... 目录一、背景二、环境三、配置nexus上传账号四、执行deploy命令上传包1. 首先需要把本地仓中要

Spring Cloud之注册中心Nacos的使用详解

《SpringCloud之注册中心Nacos的使用详解》本文介绍SpringCloudAlibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringClo... 目录Naacos服务注册/服务发现引⼊Spring Cloud Alibaba依赖引入Naco编程s依

Java springBoot初步使用websocket的代码示例

《JavaspringBoot初步使用websocket的代码示例》:本文主要介绍JavaspringBoot初步使用websocket的相关资料,WebSocket是一种实现实时双向通信的协... 目录一、什么是websocket二、依赖坐标地址1.springBoot父级依赖2.springBoot依赖

Java使用Mail构建邮件功能的完整指南

《Java使用Mail构建邮件功能的完整指南》JavaMailAPI是一个功能强大的工具,它可以帮助开发者轻松实现邮件的发送与接收功能,本文将介绍如何使用JavaMail发送和接收邮件,希望对大家有所... 目录1、简述2、主要特点3、发送样例3.1 发送纯文本邮件3.2 发送 html 邮件3.3 发送带

Java实现将byte[]转换为File对象

《Java实现将byte[]转换为File对象》这篇文章将通过一个简单的例子为大家演示Java如何实现byte[]转换为File对象,并将其上传到外部服务器,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言1. 问题背景2. 环境准备3. 实现步骤3.1 从 URL 获取图片字节数据3.2 将字节数组

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase