简单说明反射和new的区别和反射的使用代码展示

目录

1.反射的认识

2.反射和new的区别

3.反射的使用代码展示

4.反射优点和缺点


1.反射的认识

反射是Java语言的一种机制,它允许程序在运行时检查和操作类、方法、字段等信息,而不需要提前知道它们的具体定义。通过反射,我们可以在运行时动态地加载类、创建对象、调用方法以及访问和修改字段。

 Java反射提供了以下核心类:

细说: 

(1)Class类:代表Java中的类或接口。通过Class类,我们可以获取类的构造函数、方法、字段等信息。

(2)Constructor类:代表类的构造函数。通过Constructor类,我们可以创建对象。

(3)Method类:代表类的方法。通过Method类,我们可以调用方法。

(4)Field类:代表类的字段。通过Field类,我们可以访问和修改字段的值。

  Java 文件被编译后,生成了 .class 文件, JVM 此时就要去解读 .class 文件 , 被编译后的 Java 文件 .class 也被 JVM 解析为 一个对象,这个对象就是 java.lang.Class . 这样当程序在运行时,每个 java 文件就最终变成了 Class 类对象的一个实 例。我们通过Java 的反射机制应用到这个实例,就可以去 获得甚至去添加改变这个类的属性和动作 ,使得这个类成 为一个动态的类。

2.反射和new的区别

仅仅在实例化对象上效果无区别,接下来我会列举一些反射和new重要的区别(不阐述底层原理,只区分不同)

(1)首先new出来的对象我们无法访问其中的私有属性,但是通过反射出来的对象我们可以通过setAccessible()方法来访问其中的私有属性。

(2)new对象一定要知道类名(在不知道类名的情况下,你怎么去new?),但反射创建对象不需要知道类名也可以。

(3)new对象属于静态编译,也就是说当代码生成exe文件的时候会将所有模块都编译进去,当你启动这个exe文件的时候,所有模块就会进行一个加载的过程(初始化)

 反射属于动态编译,编译过程中并不会将模块编译进去,这样初始化的时候就会减少负荷,只有在运行过程中,需要哪些模块的时候才进行调用.


3.反射的使用代码展示

我们先看看Class类中的相关方法

(1)常用获得类相关的方法

(2)常用获得类中属性相关的方法(以下方法返回值为Field相关)

(3) 获得类中注解相关的方法

(4)获得类中构造器相关的方法(以下方法返回值为Constructor相关)

 (5) 获得类中方法相关的方法(以下方法返回值为Method相关)

在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息

接下来展示代码需要导入的包:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


3.1获得Class对象的三种方式

student类

class Student {//私有属性nameprivate String name = "wang";//公有属性agepublic int age = 18;//不带参数的构造方法public Student(){System.out.println("Student()");}private Student(String name,int age) {this.name = name;this.age = age;System.out.println("Student(String,name)");}private void eat(){System.out.println("i am eat");}public void sleep(){System.out.println("i am pig");}private void function(String str) {System.out.println(str);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

 Text类

public class Test {/*Class对象 只有一个*/public static void main(String[] args) {Class<?> c1 = null;try {c1 = Class.forName("demo1.Student");}catch (ClassNotFoundException e) {e.printStackTrace();}Class<?> c2 = Student.class;Student student = new Student();Class<?> c3 = student.getClass();}
}

说明:

(1)直接通过 类名 .class 的方式得到 , 该方法最为安全可靠,程序性能更高
这说明任何一个类都有一个隐含的静态成员变量 class
(2) 通过 Class 对象的 forName() 静态方法来获取,用的最多,
但可能抛出 ClassNotFoundException 异常, 注意这里是类的全路径,如果有包需要加包的路径

思考: 

提问: 关于Text类
        System.out.println(c1 == c2);
        System.out.println(c1 == c3);

答案:ture     ture

因为:Class对象 只有一个 一个类在 JVM 中只会有一个 Class 实例

接下来我们开始使用反射,我们依旧反射上面的Student类,把反射的逻辑写到另外的类当中进行理解

以下均为简单操作,故不做过多说明。

3.2反射机制创建对象

代码:

 public static void reflectNewInstance() {Class<?> classStudent = null;try {classStudent = Class.forName("demo1.Student");Student student = (Student)classStudent.newInstance();System.out.println(student);}catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}

通过反射机制调用构造方法实例化java对象

代码:

 public static void reflectPrivateConstructor() {Class<?> classStudent = null;try {classStudent = Class.forName("demo1.Student");//获得构造方法Constructor<?> constructor = classStudent.getDeclaredConstructor(String.class,int.class);constructor.setAccessible(true);Student student = (Student)constructor.newInstance("xiaoming",15);System.out.println(student);}catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}

 小结:

  1. 先获取到这个有参数的构造方法【用ClassgetDeclaredConstructor()方法获取】
  2. 调用构造方法new对象【用Constructor类的newInstance()方法new对象】

3.3通过反射机制访问一个java对象的属性

代码:

    public static void reflectPrivateField() {Class<?> classStudent = null;try {classStudent = Class.forName("demo1.Student");Field field = classStudent.getDeclaredField("name");field.setAccessible(true);Student student = (Student)classStudent.newInstance();field.set(student,"caocao");System.out.println(student);}catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchFieldException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}

3.4通过反射机制调用一个对象的方法

代码:

 public static void reflectPrivateMethod() {Class<?> classStudent = null;try {classStudent = Class.forName("demo1.Student");Method method = classStudent.getDeclaredMethod("function",String.class);method.setAccessible(true);Student student = (Student)classStudent.newInstance();method.invoke(student,"我是一个反射的参数!");}catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}

4.反射优点和缺点

优点:

(1)对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法

(2)增加程序的灵活性和扩展性,降低耦合性,提高自适应能力

(3)反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺点:

(1)使用反射会有效率问题。会导致程序效率降低。具体参考这里:反射效率低的原因

(2)反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

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

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

相关文章

Redis缓存(缓存预热,缓存穿透,缓存雪崩,缓存击穿)

目录 一, 缓存 1, 什么是缓存 2, 什么是热点数据(热词) 3, 缓存更新策略 3.1 定期生成 3.2 实时生成 二, Redis缓存可能出现的问题 1, 缓存预热 1.1 什么是缓存预热 1.2 缓存预热的过程 2, 缓存穿透 2.1 什么是缓存穿透 2.2 缓存穿透产生的原因 2.3 缓存穿透的解…

图论03-【无权无向】-图的深度优先DFS遍历-路径问题/检测环/二分图

文章目录 1. 代码仓库2. 单源路径2.1 思路2.2 主要代码 3. 所有点对路径3.1 思路3.2 主要代码 4. 路径问题的优化-提前结束递归4.1 思路4.2 主要代码 5. 检测环5.1 思路5.2 主要代码 6. 二分图6.1 思路6.2 主要代码6.2.1 遍历每个联通分量6.2.2 递归判断相邻两点的颜色是否一致…

概念解析 | 毫米波雷达与计算机视觉的融合

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:毫米波雷达与计算机视觉的融合。 毫米波雷达与计算机视觉的融合 Sensors | Free Full-Text | MmWave Radar and Vision Fusion for Object Detection in Autonomous Driving: A …

最详细STM32,cubeMX串口发送,接收数据

这篇文章将详细介绍 串口 发送数据&#xff0c;接受数据。 文章目录 前言一、串口的基础知识二、cubeMX 配置三、自动生成代码解析四、串口发送数据函数五、使用串口收发数据点亮 led重定向函数&#xff1a; 总结 前言 实验开发板&#xff1a;STM32F103C8T6。所需软件&#xf…

pycharm操作git、前后端项目上传到gitee

pycharm操作git 之前用命令做的所有操作&#xff0c;使用pychrm点点就可以完成 克隆代码 上方工具栏Git ⇢ \dashrightarrow ⇢ Clone ⇢ \dashrightarrow ⇢ 填写地址&#xff08;http、ssh&#xff09; 提交到暂存区&#xff0c;提交到版本库&#xff0c;推送到远程 直接…

rust学习——函数返回值

概念 Rust 中的函数定义以 fn 开始&#xff0c;后跟着函数名和一对圆括号。大括号告诉编译器函数体在哪里开始和结束。 特殊的地方——函数返回值 错误的写法 正解1 去掉分号 fn main() {let x plus_one(5);println!("The value of x is: {}", x); }fn plus_…

【小白专用 已验证】PHP连接SQLServer数据库

PHP是一门强大的服务器端脚本语言&#xff0c;而SQL Server是Microsoft开发的一款关系型数据库管理系统。为了在PHP中直接操纵SQL Server数据库&#xff0c;需要通过安装SQL Server扩展来实现。这篇文章将详细介绍如何在PHP中使用SQL Server扩展来操作数据库。 首先&#xff0…

linux/kali2023.1工具集合()

1 系统硬件信息查询 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性 hdparm -tT /dev/sda 在磁盘上执行测试性读取操作 cat /p…

使用 Rust 和 cURL 库下载程序

以下是一个使用 Rust 和 cURL 库的下载器程序&#xff0c;用于下载 图像。此程序使用了 https://www.duoip.cn/get_proxy 的代码。 extern crate curl; ​ use std::io::{self, Read}; use std::error::Error; ​ fn main() {let url "https://www.baidu.com";let …

Access,Trunk,Hybrid的一些接触知识以及实验

VLAN基本配置 一、实验目的 1.掌握VLAN基础配置原理&#xff1b; 2.掌握Access接口工作原理及配置&#xff1b; 3.掌握Trunk接口工作原理及配置&#xff1b; 4.掌握Hybrid接口工作原理及配置。 二、实验设备 1.电脑1台&#xff1b; 2.ENSP仿真软件。 三、实验内容及步骤 VLAN( …

论文阅读:Efficient Point Cloud Segmentation with Geometry-Aware Sparse Networks

来源&#xff1a;ECCV2022 链接&#xff1a;Efficient Point Cloud Segmentation with Geometry-Aware Sparse Networks | SpringerLink 0、Abstract 在点云学习中&#xff0c;稀疏性和几何性是两个核心特性。近年来&#xff0c;为了提高点云语义分割的性能&#xff0c;人们提…

【网络编程】应用层——HTTP协议

文章目录 一、HTTP协议简介二、认识URL三、HTTP协议格式1. HTTP请求协议格式2. HTTP响应协议格式 三、构建HTTP请求和响应四、HTTP的方法五、HTTP的状态码六、HTTP常见的Header七、Cookie和Session 一、HTTP协议简介 HTTP 协议 是 Hyper Text Transfer Protocol&#xff08;超文…

给Windows文件夹添加备注信息

自己的电脑中文件夹为了安装各种开发环境&#xff0c;基本都是英文字母命名&#xff0c;就导致好多东西猛地一看找不着。此时加个备注会不会就好很多呢&#xff1f;就如以下这种 设置方法&#xff1a; 1、展示备注 右键展示的列表头部&#xff0c;会出现展示项&#xff0c;一…

AD9371 官方例程HDL详解之JESD204B TX_CLK生成 (二)

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 &#xff1a; AD9371 官方…

Metabase:简单快捷的商业智能与数据分析工具 | 开源日报 No.61

moby/moby Stars: 66.8k License: Apache-2.0 Moby 是一个由 Docker 创建的开源项目&#xff0c;旨在实现和加速软件容器化。它提供了工具包组件的“乐高集”&#xff0c;可以将它们组装成基于容器的自定义系统的框架。组件包括容器生成工具、容器注册表、业务流程工具、运行时…

折半搜索-oier复健练习题目

算法介绍&#xff1a; 折半搜索常用于复杂度O(n!)级的搜索问题&#xff0c;当我们发现很显然可以将问题划分为两部分分别搜索枚举&#xff0c;再合二为一求出最终答案时&#xff0c;我们可以选择使用折半搜索。 常见数据规模&#xff1a; 对于答案的值域往往没有要求&#x…

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

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

位操作符^以及正负数在计算机中的存储

(数据是怎么在计算机中存储的)​ 正数和负数在内存中都是以补码的形式存储的&#xff0c;但不同的是正数的原码&#xff0c;补码&#xff0c;反码都是相同的&#xff0c;而负数的原码&#xff0c;补码和反码是不同的。 负数的原码&#xff0c;补码&#xff0c;反码之间存在什么…

git创建与合并分支

文章目录 创建与合并分支分支管理的概念实际操作 解决冲突分支管理策略Bug分支Feature分支多人协作 创建与合并分支 分支管理的概念 分支在实际中有什么用呢&#xff1f;假设你准备开发一个新功能&#xff0c;但是需要两周才能完成&#xff0c;第一周你写了50%的代码&#xf…

详细介绍如何使用Ipopt非线性求解器求解带约束的最优化问题

本文中将详细介绍如何使用Ipopt非线性求解器求解带约束的最优化问题&#xff0c;结合给出的带约束的最优化问题示例&#xff0c;给出相应的完整的C程序&#xff0c;并给出详细的解释和注释&#xff0c;以及编译规则等 一、Ipopt库的安装和测试 本部分内容在之前的文章《Ubuntu2…