反射理解【精细】

目录

什么是反射

                从编程的角度来说 :

                从生活的角度来说 :

Class类

记住一句话:  

获取Class对象的三种方法 :

通过Class.forName("包名.类名")获取class对象 (方法一)

通过类名.class获取Class对象(方法二)

通过 对象.class 获取Class对象

获取Class类总结 :

反射Api使用

newInstance()使用

getConstructor(型参类型.class,型参类型.class,…) 

Field

getFields();

getDeclaredFields() ;


什么是反射

                从编程的角度来说 :

                                反射就是把java类中的各种成分映射成一个个的Java对象

                                通过反射,在程序运行时,可以动态获取一个类的所有属性,方法,包括(私有的)!!!!

                从生活的角度来说 :

                            1.当你站在镜子前时,你可以看到自己的外貌:你的发型、穿着和身体状况等。这就类似于在 Java 中使用反射来查看一个类的信息,比如类的名字、它的方法、字段和其他外部特征。

                            2.在现实生活中,你可能会在看镜子后决定改变某些东西,比如换一种发型或换一件衣服。在 Java 反射中,这就相当于改变对象的状态或行为,例如修改一个对象的属性值或调用它的某个方法。


Class类

记住一句话:  

         只要是类,他就有class对象,反射都是基于class对象去操作的!!!

                每个类都有一个 Class 对象,它用来创建这个类的所有对象,反过来说,每个类的所有对象都会关联同一个 Class 对象(对于数组来说,维数、类型一致的数组的 Class 对象才是相同的) , 每个对象的创建都依赖于 Class 对象的是否创建,Class 对象的创建发生在类加载(java.lang.ClassLoader)的时候。


获取Class对象的三种方法 :

通过Class.forName("包名.类名")获取class对象 (方法一)

        第一步 :

                创建一个Student类

package com.xr.ademo;// 第一步 : 创建一个Student 类,有属性,有构造方法,有getter,setter方法(标准的javaBean类)
public class Student {private String name; // 姓名private String sex; // 年龄/*无参构造*/public Student() {}/*全参构造*/public Student(String name, String sex) {this.name = name;this.sex = sex;}/*属性的getter,setter方法*/public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}
}

第二步: 

             定义一个测试类,并使用Class.forNam();方法

package com.xr.aDemo;
import java.lang.reflect.Method;public class StudentTest {public static void main(String[] args) throws Exception {//第二步: 通过Class.forName()方法获取class对象// 使用forName方法时需要抛出异常,因为肯能获取的类为空!!!!Class<?> clazz = Class.forName("com.xr.aDemo.Student");// 获取类中的所有公共方法,不包括私有方法Method[] methods = clazz.getMethods();//循环遍历所有公共方法for (Method method : methods) {//输出公共方法的名称System.out.println(method.getName());}}
}

forName();  方法的参数就是你所要获取的类路径

        上面的forName参数就是 com.xr.aDemo.Student

最后输出结果为 :

为什么除了我们自己定义的get,set方法还有其他方法名称呢???

        因为我们自己定义的类,(只要是类)都会隐式继承父类(Object),所以有其他的方法,指向的为父类的方法


通过类名.class获取Class对象(方法二)

        第一步:

                还是接着上面方法1定义的Student类使用

        第二步:

                编写测试类使用类名.class获取class对象

package com.xr.aDemo;
import java.lang.reflect.Method;public class StudentTest {public static void main(String[] args) {//第二步: 通过类名.class获取Class对象Class<Student> studentClass = Student.class;// 获取类中的所有公共方法    Method[] methods = studentClass.getMethods();// 循环遍历公共方法for (Method method : methods) {// 输出方法名称System.out.println(method.getName());}}
}

最后运行结果为:


通过 对象.class 获取Class对象

        第一步 :

                还是接着上面方法1定义的Student类使用

        第二步 :

                创建一个测试类,并使用 对象.class 获取Class独享

package com.xr.aDemo;
import java.lang.reflect.Method;public class StudentTest {public static void main(String[] args) {//第二步: 创建Student对象Student student = new Student();//第三步: 通过对象.getClass获取Class对象Class<? extends Student> clazz = student.getClass();//第四步: 获取所有的公共方法Method[] methods = clazz.getMethods();//第五步: 遍历功公共方法for (Method method : methods) {System.out.println(method.getName());}}
}

最后运行结果:


获取Class类总结 :

这三种方式都是获取Class对象的方法,但一般推荐使用的是第一种方法【Class.forName()】方法。

因为第二种方法【类名.class】方法需要导包,而第三种方法【对象.class】方法需要先创建对象之后,在通过对象名称的class获取Class对象,但是设想一下,我都有了Student对象,已经有了他的属性和方法,我还需要反射获取他嘛,所以推荐第一种方法


反射Api使用

newInstance()使用

newInstance()方法的作用 : 动态创建类的对象,动态创建类的实例

        第一步重新创建一个Student类

package com.xr.aDemo;// 第一步 : 创建一个Student 类,有属性,有构造方法,有getter,setter方法(标准的javaBean类)
// 还有其他方法,并重新写了ToString()方法
public class Student {private String name; //姓名private int age; // 年龄private float weight; // 体重private static final double PI = 3.14; // 圆周率/*构造方法*/public Student() {}public Student(String name, int age, float weight) {this.name = name;this.age = age;this.weight = weight;}public Student(String name, Float weight) {this.name = name;this.age = 18;this.weight = weight;}/*getter,setter方法*/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;}public float getWeight() {return weight;}public void setWeight(float weight) {this.weight = weight;}/*其他方法*/public void hello() {System.out.println("你好!");}private void sleep() {System.out.println("睡觉了!");}public void sayHello(String who) {System.out.println("你好," + who);}public int sum(int i, int j) {return i + j;}/*重写toString方法*/@Overridepublic String toString() {return this.getName()+","+this.getAge()+","+this.getWeight() ;}
}

第二步 :

        编写测试类,使用newInstance()方法创建对象的实例

package com.xr.aDemo;
import java.lang.reflect.Method;public class StudentTest {public static void main(String[] args) throws Exception {// 第二步,通过class.forName()方法获取Class对象,使用forName()需要抛出异常Class<?> clazz = Class.forName("com.xr.aDemo.Student");//第三步: 通过Class对象的newInstance()方法来实例化对象Student student = (Student) clazz.newInstance();//第四步: 既然有了student对象,就可以随便调用student类里面的方法了student.hello();student.sayHello("张三");}
}

最后调用方法的结果:


getConstructor(型参类型.class,型参类型.class,…) 

getCounstructor()的作用:获取有参数的构造方法信息

第一步:

        还是接着上面的Student类使用

第二步:

        创建测试类,使用 getConstructor(); 获取重载构造方法,并实例化

package com.xr.aDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class StudentTest {public static void main(String[] args) throws Exception {// 第二步,通过class.forName()方法获取Class对象,使用forName()需要抛出异常Class<?> clazz = Class.forName("com.xr.aDemo.Student");// 第三步, 通过getConstructor()方法获取构造器对象//这里的值是与构造器参数类型一致的参数列表的class对象Constructor<?> constructor = clazz.getConstructor(String.class, int.class, float.class);// 第四步, 通过构造器对象获取实例对象Object obj = constructor.newInstance("张三", 18, 60.0f);//转型成Student对象Student student = (Student) obj;//输出student对象System.out.println(student);}
}

注意:

        getConstructor()方法里面的参数,一定要与你定义的构造方法中的参数类型对应,并获取对应的类型class对象,将对应的类型Class对象做为参数

这句代码中的参数,与下面截图对应的构造方法类型对应

Constructor<?> constructor = clazz.getConstructor(String.class, int.class, float.class);

最后运行的结果为:

这个方法总结:

重点:

getConstructor()这个方法说白了就是获取有参的构造方法的实例;

而newInstance()这个方法直接获取无参的构造方法的实例;


Field

getFields();

获取所有公共的字段;

还是接着上面的student类,但是增加一个公共属性

第二步:

        通过getFields()方法获取所有公共属性

package com.xr.aDemo;
import java.lang.reflect.Field;public class StudentTest {public static void main(String[] args) throws Exception {// 第二步,通过class.forName()方法获取Class对象,使用forName()需要抛出异常Class<?> clazz = Class.forName("com.xr.aDemo.Student");//第三步: 通过getFields()方法获取所有公共属性Field[] field = clazz.getFields();//第四步: 循环遍历所有属性for (Field f : field) {System.out.println("属性名:" + f.getName());}}
}

最后结果:


getDeclaredFields() ;

获取所有的字段(是所有,不管你是公开还是私有.......等等)

第一步:

        还是那个Studnet类,并增加了一个公共字段

第二步 :

        使用getDeclaredFields()方法获取所有属性

package com.xr.aDemo;
import java.lang.reflect.Field;public class StudentTest {public static void main(String[] args) throws Exception {// 第二步,通过class.forName()方法获取Class对象,使用forName()需要抛出异常Class<?> clazz = Class.forName("com.xr.aDemo.Student");//第三步: 通过getFields()方法获取所有属性(不管是什么访问的修饰符)Field[] field = clazz.getDeclaredFields();//第四步: 循环遍历所有属性for (Field f : field) {System.out.println("属性名:" + f.getName());}}
}

最后的结果为:

----------------------待更新

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

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

相关文章

使用Jest测试框架测试JS项目

前言 JavaScript的测试框架有很多&#xff0c;这里主要记录一些自己在初次使用jest时遇到的一些问题。详细使用文档可以参照官方说明文档。 简介 Jest 是一款优雅、简洁的 JavaScript 测试框架。 Jest 支持 Babel、TypeScript、Node、React、Angular、Vue 等诸多框架&#…

深度学习之基础模型——循环神经网络RNN

相关资料 &#xff08;1&#xff09;What are Recurrent Neural Networks? | IBM &#xff08;2&#xff09;浅析循环神经网络(RNN)的反向求导过程 - 知乎 (zhihu.com) 总共有四篇 &#xff08;3&#xff09;循环神经网络&#xff08;RNN&#xff09;浅析 - 简书 (jianshu.co…

【React】Day6

项目搭建 基于CRA创建项目 CRA是一个底层基于webpack快速创建React项目的脚手架工具 # 使用npx创建项目 npx create-react-app react-jike# 进入到项 cd react-jike# 启动项目 npm start调整项目目录结构 -src-apis 项目接口函数-assets 项目资源文件&…

springboot3 集成knife4j

knife4j介绍 Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案。 springdoc地址&#xff1a;OpenAPI 3 Library for spring-boot Knife4j官网地址&#xff1a;Knife4j 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j 环境介绍 java&#xff1a;17 Spring…

java 溯本求源之基础(十八)之Monitoring--jmc

1.JMC概述 JMC全称Java Mission Control&#xff0c;集成了多个功能强大的组件&#xff0c;其中最核心的两部分是管理控制台和Java Flight Recorder。管理控制台允许开发者实时监控应用的运行状态&#xff0c;捕捉各种性能指标&#xff1b;而Java Flight Recorder则提供了一种高…

ELK日志系统的搭建

文章目录 简介软件准备安装JDK下载Elasticsearch软件修改配置信息创建ElasticSearch运行用户、启动服务添加防火墙策略ElasticSearch-Head插件安装 安装Kibana下载软件包修改配置启动服务 安装Logstash安装包下载安装服务配置修改配置pipeline流水线服务配置文件 启动服务 全流…

腾讯云轻量应用服务器和CVM S5服务器有什么区别?

腾讯云轻量应用服务器和CVM云服务器S5有什么不同&#xff1f;性能哪个更好一些&#xff1f;CVM S5云服务器CPU采用2.5GHz主频的Intel Xeon Cascade Lake或者Intel Xeon Cooper Lake处理器&#xff0c;轻量不支持指定CPU&#xff0c;从功能、内网连通性、集群及公网带宽等方面对…

邂逅JavaScript逆向爬虫-------基础语法篇之面向对象

目录 一、概念二、对象的创建和操作2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承3.3.1 对象的原型式继承3.3.2 …

并发编程之线程通信及Condition的原理分析

1. synchronized中的线程通信 调用wait方法会使线程处于等待状态&#xff0c;直到另一个线程调用notify线程才会唤醒等待中的某个线程&#xff0c;生产者和消费者模型可以很好的使用到该例子。 生产者代码: public class Producer implements Runnable {private Queue<Str…

虚拟现实(VR)的应用场景

虚拟现实&#xff08;VR&#xff09;技术创建和体验三维虚拟世界的计算机仿真技术。用户通过佩戴VR头显等设备&#xff0c;可以完全沉浸在虚拟世界中&#xff0c;并与虚拟世界中的物体进行交互。VR技术具有广泛的应用前景&#xff0c;可以应用于各行各业。以下是一些VR的应用场…

STM32标准库编程与51单片机直接写寄存器的区别和联系

简介&#xff1a; 在学完51单片机之后&#xff0c;我们去学习32的时候&#xff0c;会发现编程的方法有很大的区别&#xff0c;让人非常的不适应&#xff0c;但是通过不断的调用相应外设的库函数之后&#xff0c;你也可以去编程STM32&#xff0c;来实现功能&#xff0c;但是你真…

SQL的基础语句

1、select语句 select colums from table_name 2、条件语句 #查询出查询出用户id为1和3的用户记录 IN 操作符允许我们在 WHERE 子句中规定多个值。 select * from student where id in (1,3) #查询出所有姓王的同学 模糊查询 like 通配符(% 任意多个字符 _单个字符) #下例…

如何使用渐变块创建自定义聊天机器人

如何使用渐变块创建自定义聊天机器人 文章目录 如何使用渐变块创建自定义聊天机器人一、介绍二、参考示例1、一个简单的聊天机器人演示2、将流式传输添加到您的聊天机器人3、喜欢/不喜欢聊天消息4、添加 Markdown、图像、音频或视频 一、介绍 **重要提示&#xff1a;**如果您刚…

软考高级架构师:AI 通俗讲解负载测试、压力测试、强度测试、容量测试和可靠性测试

在软件工程领域&#xff0c;测试是一个确保软件质量和性能的关键步骤。负载测试、压力测试、强度测试、容量测试和可靠性测试都是性能测试的不同类型&#xff0c;它们的目的和方法有所不同。 下面我将通过简单的比喻和解释&#xff0c;帮助您理解这些测试之间的区别。 负载测试…

跳跃游戏 II (贪心, 动态规划)

题目描述(力扣45题) : 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到…

使用Unity扫描场景内的二维码,使用插件ZXing

使用Unity扫描场景内的二维码&#xff0c;使用插件ZXing 使用Unity扫描场景内的二维码&#xff0c;ZXing可能没有提供场景内扫描的方法&#xff0c;只有调用真实摄像机扫描二维码的方法。 实现的原理是&#xff1a;在摄像机上添加脚本&#xff0c;发射射线&#xff0c;当射线打…

【面试八股总结】Linux系统下的I/O多路复用

参考资料 &#xff1a;小林Coding、阿秀、代码随想录 I/O多路复用是⼀种在单个线程或进程中处理多个输入和输出操作的机制。它允许单个进程同时监视多个文件描述符(通常是套接字)&#xff0c;一旦某个描述符就绪&#xff08;一般是读就绪或者写就绪&#xff09;&#xff0c;能够…

分享三个转换速度快、准确率高的视频转文字工具

想要直接将视频转换成文字&#xff0c;转换工具很重要&#xff01;给大家分享三个转换速度快、准确率高的视频转文字工具&#xff0c;轻松完成转换。 1.网易见外 https://sight.youdao.com/ 网易家的智能转写翻译服务工作站&#xff0c;网页端就可以直接使用&#xff0c;支持视…

Spring Bean依赖注入-Spring入门(二)

1、SpringBean概述 在Spring中&#xff0c;一切Java对象都被视为Bean&#xff0c;用于实现某个具体功能。 Bean的依赖关系注入的过程&#xff0c;也称为Bean的装配过程。 Bean的装配方式有3种&#xff1a; XML配置文件注解Java类 Spring中常用的两种装配方式分别是基于XML的…

Codeforces Round 821 (Div. 2) D2. Zero-One

题目 #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e5 5, inf 1e18, maxm 4e4 5; const int N 1e6;c…