P02 反射

news/2024/5/19 3:24:24/文章来源:https://blog.csdn.net/qq_35132089/article/details/126964963

P02 反射

  • 1.反射概述
    • 1.1 反射的基本作用
    • 1.2 反射的关键
  • 2.反射获取类对象
    • 2.1 forName(String className)
    • 2.2 类名.class
    • 2.3 对象.getClass()
  • 3.反射获取构造器对象![在这里插入图片描述](https://img-blog.csdnimg.cn/e234dd155af94a5c80223d64b112f4bf.png)
    • 3.1 Class 类中用于获取构造器的方法
    • 3.2 Constructor 类中常用方法
    • 3.3 测试案例
  • 4.反射获取成员变量对象
    • 4.1 Class 类中用于获取成员变量的方法
    • 4.2 Field 类中常用方法
    • 4.3 测试案例
  • 5.反射获取方法对象
    • 5.1 Class 类中用于获取成员方法的方法
    • 5.2 Method 类中常用方法
    • 5.3 测试案例
  • 6.反射的作用
    • 6.1 绕过编译阶段为集合添加数据
    • 6.2 通过框架的底层原理
      • 6.2.1 需求分析
      • 6.2.2 代码实例
      • 6.2.3 运行结果

系统:Win10
Java:1.8.0_333
IDEA:2020.3.4
Gitee:https://gitee.com/lijinjiang01/JavaWeb

1.反射概述

1.1 反射的基本作用

反射:反射是指对于任何一个 Class 类,在“运行的时候”都可以直接得到这个类全部成分
在运行时,可以直接得到这个类的构造器对象:Constructor
在运行时,可以直接得到这个类的成员变量对象:Field
在运行时,可以直接得到这个类的成员方法对象:Method
这种运行时动态获取类信息以及动态调用类中成分的能力称为 Java 语言的反射机制

1.2 反射的关键

反射第一步都是先得到编译后的 Class 类对象,然后就可以得到 Class 的全部成分
反射的核心思想和关键就是:得到编译以后的 class 文件对象
在这里插入图片描述

2.反射获取类对象

在这里插入图片描述

获取 Class 类对象的三种方式:

2.1 forName(String className)

Class 类中的一个静态方法:forName(String className)

Class c1 = Class.forName("com.lijinjiang.reflect01_class.Student");

2.2 类名.class

Class c2 = Student.class;

2.3 对象.getClass()

利用 Object 对象的 getClass() 方法获取对象对应类的 Class 对象

Student stu = new Student();
Class c3 = stu.getClass();

3.反射获取构造器对象在这里插入图片描述

3.1 Class 类中用于获取构造器的方法

方法说明
Constructor[] getConstructors()返回所有公共构造器对象的数组
Constructor[] getDeclaredConstructors()返回所有构造器对象的数组,存在就能拿到
Constructor getConstructor(Class… parameterTypes)返回指定的公共构造器对象
Constructor getDeclaredConstructor(Class… parameterTypes)返回指定的构造器对象,存在就能拿到

3.2 Constructor 类中常用方法

方法说明
T newInstance(Object… initargs)根据执行的构造器创建对象
void setAccessible(boolean flag)设置为true,表示取消访问检查,进行暴力反射

3.3 测试案例

首先创建 Student 类对象

public class Student {private String name;private int age;private Student() {System.out.println("无参构造器执行");}private Student(String name){this.name = name;System.out.println("有参构造器执行");}public Student(String name, int age) {this.name = name;this.age = age;System.out.println("全参构造器执行");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

测试获取构造器方法

import org.junit.Test;
import java.lang.reflect.Constructor;public class TestConstructor01 {// 1.getConstructors@Testpublic void testGetConstructors() {// 1.获取类对象Class c = Student.class;// 2.获取所有类对象的公共构造器Constructor[] constructors = c.getConstructors();// 3.遍历for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}}// 2.getDeclaredConstructors@Testpublic void testGetDeclaredConstructors() {// 1.获取类对象Class c = Student.class;// 2.获取所有类对象的构造器Constructor[] constructors = c.getDeclaredConstructors();// 3.遍历for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}}// 3.getConstructor(Class<?>... parameterTypes)@Testpublic void testGetConstructor() throws Exception {// 1.获取类对象Class c = Student.class;// 2.获取所有类对象的构造器Constructor constructor = c.getConstructor(String.class, int.class);// 3.输出System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}// 4.getDeclaredConstructor(Class<?>... parameterTypes)@Testpublic void testGetDeclaredConstructor() throws Exception {// 1.获取类对象Class c = Student.class;// 2.获取所有类对象的构造器Constructor constructor = c.getDeclaredConstructor();// 3.输出System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());}
}

测试使用构器创建对象方法

import org.junit.Test;
import java.lang.reflect.Constructor;public class TestConstructor02 {// 1.T newInstance(Object... initargs)@Testpublic void testNewInstance() throws Exception {// 1.获取类对象Class c = Student.class;// 2.获取Student(String name)构造器,并以此创建对象Constructor c01 = c.getDeclaredConstructor(String.class);c01.setAccessible(true); // 暴力反射Student stu01 = (Student) c01.newInstance("张三");System.out.println(stu01);// 3.获取Student(String name, int age)构造器,并以此创建对象Constructor c02 = c.getDeclaredConstructor(String.class,int.class);Student stu02 = (Student) c02.newInstance("李四",27);System.out.println(stu02);}
}

4.反射获取成员变量对象

在这里插入图片描述

4.1 Class 类中用于获取成员变量的方法

方法说明
Field[] getFields()返回所有公共成员变量对象的数组
Field[] getDeclaredFields()返回所有成员变量对象的数组,存在就能拿到
Field getField(String name)返回指定公共成员变量对象
Field getDeclaredField(String name)返回指定成员变量对象,存在就能拿到

4.2 Field 类中常用方法

方法说明
void set(Object obj, Object value)给指定对象的此成员变量设置指定的新值
Object get(Object obj)获取指定对象的该成员变量的值
void setAccessible(boolean flag)暴力反射,设置为true可以直接访问私有属性的变量
Class getType()获取变量的类型,返回类型Class对象
String getName()获取变量的名称

4.3 测试案例

首先创建 Student 类对象

public class Student {private String name;private int age;public static String school;public static final String COUNTRY = "中国";public Student() {}private Student(String name) {this.name = name;}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

测试获取成员变量的方法

import org.junit.Test;
import java.lang.reflect.Field;public class TestField01 {// 1.getFields()// 2.getDeclaredFields()@Testpublic void testGetDeclaredFields() {// 1.获取 class 对象Class c = Student.class;// 2.获取公共成员变量数组Field[] fields = c.getDeclaredFields();// 3.遍历for (Field field : fields) {System.out.println(field.getName() + "===>" + field.getType());}}// 3.getField(String name)// 4.getDeclaredField(String name)@Testpublic void testGetDeclaredField() throws Exception {// 1.获取 class 对象Class c = Student.class;// 2.获取公共成员变量数组Field field = c.getDeclaredField("age");// 3.输出System.out.println(field.getName() + "===>" + field.getType());}
}

测试成员变量的赋值和取值方法

import org.junit.Test;
import java.lang.reflect.Field;public class TestField02 {@Testpublic void testSetField() throws Exception {// 1.获取class对象Class c = Student.class;// 2.获取指定成员变量Field field = c.getDeclaredField("age");field.setAccessible(true);// 3.赋值Student stu01 = new Student();field.set(stu01, 18);System.out.println(stu01);// 4.取值Student stu02 = new Student("李四", 27);int age = (int) field.get(stu02);System.out.println(age);}
}

5.反射获取方法对象

在这里插入图片描述

5.1 Class 类中用于获取成员方法的方法

方法说明
Method[] getMethods()返回所有公共成员方法对象的数组
Method[] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到
Method getMethod(String name, Class… parameterTypes)返回指定公共成员方法对象
Method getDeclaredMethod(String name, Class… parameterTypes)返回指定成员方法对象,存在就能拿到

5.2 Method 类中常用方法

方法说明
Object invoke(Object obj, Object… args)运行方法
参数一:用obj对象调用该方法
参数二:调用方法传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
void setAccessible(boolean flag)暴力反射,设置为true可以直接调用私有方法运行

5.3 测试案例

首先创建 Dog 类对象

public class Dog {private String name;public Dog() {}public Dog(String name) {this.name = name;}public void run() {System.out.println("小狗跑的飞快");}private void eat() {System.out.println("狗吃骨头");}private String eat(String name) {System.out.println("狗在吃" + name);return "吃的很开心";}public static void inAddr() {System.out.println("在上海有一只单身狗");}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

测试获取成员方法的方法以及测试方法运行的方法

import org.junit.Test;
import java.lang.reflect.Method;public class TestMethod01 {// 1.getMethods()// 2.getDeclaredMethods()@Testpublic void testGetDeclaredMethods() {// 1.获取 class 对象Class c = Dog.class;// 2.获取成员方法数组Method[] methods = c.getDeclaredMethods();// 3.遍历for (Method method : methods) {System.out.println(method.getName() + " 返回值类型" + method.getReturnType() + " 参数个数" + method.getParameterCount());}}// 3.getMethod(String name, Class<?>... parameterTypes)// 4.getDeclaredMethod(String name, Class<?>... parameterTypes)@Testpublic void testGetDeclaredMethod() throws Exception {// 1.获取 class 对象Class c = Dog.class;// 2.获取成员方法数组Method method01 = c.getDeclaredMethod("eat");method01.setAccessible(true);Method method02 = c.getDeclaredMethod("eat",String.class);method02.setAccessible(true);// 3.执行方法Dog dog = new Dog();Object res01 = method01.invoke(dog);Object res02 = method02.invoke(dog, "稀饭");System.out.println(res01);System.out.println(res02);}
}

6.反射的作用

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

反射是作用在运行时的技术,此时集合的泛型将不能再产生约束了,此时是可以为集合存入其他任意类型的元素的
在这里插入图片描述

泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成 Class 文件进入运行阶段的时候,其真实类型都是 ArrayList 了,泛型相当于被擦除了
代码如下:

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;public class ReflectDemo {public static void main(String[] args) throws Exception {List<String> list01 = new ArrayList<>();List<Integer> list02 = new ArrayList<>();System.out.println(list01.getClass());System.out.println(list02.getClass());System.out.println(list01.getClass() == list02.getClass()); // ArrayList.classSystem.out.println("==============================");List<Integer> list03 = new ArrayList<>();list03.add(100);list03.add(200);// list03.add("三百");// 1.获取class对象Class c = list03.getClass();// 2.获取指定methodMethod method = c.getMethod("add",Object.class);// 3.运行该方法boolean b = (boolean) method.invoke(list03, "三百");System.out.println(b);System.out.println(list03);System.out.println("==============================");List list04 = list03;list04.add("四百");list04.add(true);System.out.println(list03);}
}

6.2 通过框架的底层原理

6.2.1 需求分析

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

  1. 定义一个方法,可以接收任意类的对象
  2. 使用反射获取对象的 Class 类对象,然后获取全部成员变量信息
  3. 遍历成员变量信息,然后提取本成员变量在对象中的具体值
  4. 存入成员变量名称和值到文件中去即可

6.2.2 代码实例

创建 Student、Teacher 类

public class Student {private String name;private char sex;private int age;private String classroom;private String hobby;public Student() {}public Student(String name, char sex, int age, String classroom, String hobby) {this.name = name;this.sex = sex;this.age = age;this.classroom = classroom;this.hobby = hobby;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getClassroom() {return classroom;}public void setClassroom(String classroom) {this.classroom = classroom;}public String getHobby() {return hobby;}public void setHobby(String hobby) {this.hobby = hobby;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", sex=" + sex +", age=" + age +", classroom='" + classroom + '\'' +", hobby='" + hobby + '\'' +'}';}
}
public class Teacher {private String name;private char sex;private double salary;public Teacher() {}public Teacher(String name, char sex, double salary) {this.name = name;this.sex = sex;this.salary = salary;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}@Overridepublic String toString() {return "Teacher{" +"name='" + name + '\'' +", sex=" + sex +", salary=" + salary +'}';}
}

创建工具类

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class MybatisUtil {/*** 保存任意类型的对象*/public static void save(Object obj) {try {PrintStream ps = new PrintStream(new FileOutputStream("P02_Reflect/src/com/lijinjiang/reflect06_framework/data.txt", true));// 1.获取class对象Class c = obj.getClass(); // c.getSimpleName() 获取当前类名  c.getName() 获取全限名:包名+类名String simpleName = c.getSimpleName();ps.println("===============" + simpleName + "===============");// 2.获取全部成员变量Field[] fields = c.getDeclaredFields();// 3.获取成员变量的值for (Field field : fields) {field.setAccessible(true);String name = field.getName();String value = field.get(obj) + "";ps.println(name + "=" + value);}ps.close();} catch (Exception e) {e.printStackTrace();}}
}

创建测试类

public class ReflectDemo {public static void main(String[] args) {Teacher teacher01 = new Teacher("古越涛", '男', 3999.9);Teacher teacher02 = new Teacher("裴佩", '女', 4999.0);Student student = new Student("蓝菲琳", '女', 18, "三年八班", "唱歌、跳舞");MybatisUtil.save(teacher01);MybatisUtil.save(teacher02);MybatisUtil.save(student);}
}

6.2.3 运行结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

18.Composition API(四)高级语法补充

1.自定义指令 之前我们学习了各种指令&#xff1a;v-model、v-for、v-show等&#xff0c;除了这些指令外&#xff0c;Vue允许我们自定义指令。 什么时候使用自定义指令&#xff1f; 需要对DOM元素进行底层操作&#xff0c;这个时候就会用到自定义指令。 注意&#xff1a;在V…

第二章 ES数据操作与集群

一、回顾 1.介绍ES 2.ES原理 3.ES功能 4.ES使用场景 5.ES安装 1)ES配置文件(单点配置) [root@es01 ~]# grep ^[a-z] /etc/elasticsearch/elasticsearch.yml node.name: es-1 path.data: /data/es/data path.logs: /data/es/log bootstrap.memory_lock: true network.host: 1…

Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8

因为另一台机器开发时,android studio提示更新什么东西,无脑点了。 导致原先的那台开发机器,无法build,报异常: Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8 有两个方法解决: 1、修改jdk从1.8改到11如果没有这个选项,可能需要安装…

高项重点内容

BI&#xff0c;商业智能 联机事务处理OLTP主要是执行基本日常的事务处理&#xff0c;比如数据库记录的增删查改。比如在银行的一笔交易记录&#xff0c;就是一个典型的事务。联机分析处理是数据仓库系统的主要应用&#xff0c;支持复杂的分析操作&#xff0c;侧重决策支持&…

Java高级:IO

笔记来源&#xff1a;尚硅谷Java入门视频教程(在线答疑Java面试真题) 文章目录一 File类的使用1.1 基本概述1.2 File类的常用构造器1.3 路径分隔符1.4 File类常用方法二 IO流原理及流的分类2.1 IO原理2.2 流的分类2.3 节点流和处理流2.4 InputStream & Reader2.4.1 InputSt…

mini LED显示屏—点胶测量

mini LED显示屏作为一种LED的一种技术&#xff0c;其产品已开始应用于超大屏高清显示&#xff0c;如监控指挥、高清演播、高端影院、医疗诊断、广告显示、会议会展、办公显示、虚拟现实等商用领域。 而本次测量mini LED显示屏胶水高度。测试采样步距间隔大小的测量精度&#xf…

基于PHP的校园二手信息网站的设计与实现毕业设计源码251656

目 录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3论文结构与章节安排 2 校园二手信息网站系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2…

压裂反排液除氨氮树脂技术

项目名称 中国石油工程建设除氨氮项目 工艺选择 沉淀工艺软化系统膜系统离子交换脱氨系统&#xff0c;出水稳定在0.2mg/l 工艺原理 页岩气开采反排液&#xff0c;经过沉淀工艺后进入软化系统&#xff0c;然后经过反渗透工艺后进行离子交换脱氨工艺。 下面这个案例分享是科…

戴尔笔记本重装系统硬盘加密怎么解除

​bitlocker加密可以很好地保护计算机中的数据&#xff0c;那么dell电脑硬盘的bitlocker加密如何解除 ?小编给大家介绍一下解除戴尔笔记本硬盘加密的方法。 工具/原料&#xff1a; 系统版本&#xff1a;windows10系统 品牌型号&#xff1a;戴尔 方法/步骤&#xff1a; 解…

Methyltetrazine-Maleimide,甲基四嗪-马来酰亚胺 一种可降解ADC linker

●中文名&#xff1a;甲基四嗪-马来酰亚胺 ●英文&#xff1a;Methyltetrazine-Maleimide ●外观以及性质&#xff1a;红色固体&#xff0c;Methyltetrazine-Maleimide 是一种可降解 (cleavable) 的 ADC linker&#xff0c;可用于合成抗体偶联药物 (ADC)。其次是一种点击化学马…

【云原生 | 从零开始学Kubernetes】二十二、kubernetes持久化存储下

该篇文章已经被专栏《从零开始学k8s》收录 上一篇文章&#xff1a;kubernetes持久化存储上 点击跳转 持久化存储下k8s 持久化存储&#xff1a;hostPathk8s 持久化存储&#xff1a;nfsk8s 持久化存储&#xff1a; PVCk8s PV 是什么&#xff1f;k8s PVC 是什么&#xff1f;k8s PV…

【Docker】简单搭建Portainer

既然是家用的Docker那就不上Rancher了&#xff0c;直接通过Portainer轻量化解决所有问题。还好最新的Portainer还是很人性化的&#xff0c;搭建也比较简单&#xff0c;说白了原理就是直接通过宿主机的Docker进行同调&#xff08;这个可以通过下面的启动语句得知&#xff09;。 …

MySQL数据库之进阶查询语句

目录 一、常用查询 1、按关键字查询 ①升序排序 ②降序排序 ③结合where进行条件过滤 ④多字段排序 2、and和or判断 ①and和or的使用 ②嵌套、多条件使用 3、distinct 查询不重复记录 4、group by 对结果进行分组 5、limit限制结果条目 6、设置别名&#xff…

Sentinel核心算法设计与实现

这里我们先一起了解一下Sentinel的一些比较重要的概念 ,Sentinel 整体工作流程采用责任链模式,功能定义Slot,计数通过Node,在Slot中通过选用不同的Node实现不同的流控模式。 Node 用于不同纬度的计数Slot 实现不同的功能Resource 受保护的资源Rule 保护资源规则 回顾完了S…

跟踪元素可视?试试Intersection Observer

本文将讲解Intersection Observer的用法及其polyfill的原理&#xff0c;我们一起来看下。背景现在有以下几种场景。页面滚动时懒加载图片实现无线滚动页面&#xff08;Infinite scrolling&#xff09;根据某个元素是否出现在视窗从而执行某些逻辑&#xfeff;对于这些传统的实现…

ONES 参与《软件研发效能权威指南》编写

9月16-17日&#xff0c;2022 年 QECon 全球软件质量&效能大会在上海举行&#xff0c;ONES 联合创始人兼 CTO 冯斌受邀参加本次大会&#xff0c;并做了主题为《大型软件团队项目管理数字化实践》的分享。演讲剖析了百人以上大型团队的研发管理痛点&#xff0c;并结合 ONES 丰…

Sqlserver 根据父节点ID查询所有子节点

举例: 根据父节点ID查询出所有子节点 不含父节点DECLARE @ParentID int SET @ParentID=3; with CTEGetChild as ( select * from [dbAssetCheck-yili].[dbo].[vFinaceDepartment] where PFDepartmentId=@ParentID UNION ALL (SELECT a.* from [dbAssetCheck-yili].[dbo].[vFi…

【JavaWeb篇】快速学习MyBatis|实战项目详解

作者主页&#xff1a;橙子! 主页 系列专栏&#xff1a;JavaWeb基础教程系列 精彩回顾&#xff1a;HTTP协议详解 文章目的&#xff1a;快速学习MyBatis及实战项目详解 文章目录1.什么是MyBatis?2. JDBC存在的缺点3.Mybatis简化JDBC开发4.MyBatis快速入门1.什么是MyBatis? 简单…

工具推荐-使用RedisInsight工具对Redis集群CURD操作及数据可视化和性能监控

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

Balk——你不来,我走了

模式概要 通过synchronized关键字保护&#xff0c;判断一个契机&#xff0c;如果契机满足则继续执行&#xff0c;不满足则直接返回。 与Guarded Suspension模式有显著的对比。Guarded Suspensionhttps://blog.csdn.net/Day_and_Night_2017/article/details/126945643 核心思路…