Java之反射

一、反射的概述

是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意属性和方法;
这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。


通俗的理解:

  • 利用反射创建的对象可以无视修饰符调用类里面的内容
  • 可以跟配置文件结合起来使用,把要创建的对象信息和方法写在配置文件中。
    • 读取到什么类,就创建什么类的对象
    • 读取到什么方法,就调用什么方法
    • 此时当需求变更的时候不需要修改代码,只要修改配置文件即可。

二、获取字节码文件对象的三种方式

  • Class这个类里面的静态方法forName(“全类名”)(最常用)
  • 通过class属性获取
  • 通过对象获取字节码文件对象

示例: 

public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//1. 第一种方法//    全类名:包名+类名Class clazz1 = Class.forName("ReflectDemo1.Student");System.out.println(clazz1);//2. 第二种方法Class<Student> clazz2 = Student.class;System.out.println(clazz2);//3. 第三种方法Student s = new Student();Class clazz3 = s.getClass();System.out.println(clazz3);}
}public class Student {private String name;private int age;………………
}

三、字节码文件和字节码文件对象

  • java文件:就是我们自己编写的java代码。
  • 字节码文件:就是通过java文件编译之后的class文件(是在硬盘上真实存在的,用眼睛能看到的)
  • 字节码文件对象:当class文件加载到内存之后,虚拟机自动创建出来的对象。
    • 这个对象里面至少包含了:构造方法,成员变量,成员方法。


反射获取的是什么?

        字节码文件对象,这个对象在内存中是唯一的。

四、获取构造方法

  • Constructor<?>[] getConstructors():获得所有的构造(只能public修饰)  
  • Constructor<?>[] getDeclaredConstructors():获得所有的构造(包含private修饰) 
  • Constructor<T> getConstructor(Class<?>... parameterTypes):获取指定构造(只能public修饰)   
  • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):获取指定构造(包含private修饰)

Constructor类种用于创建对象的方法

  • T newInstance(Object... initargs):根据指定的构造方法创建对象
  • setAccessible(boolean flag):设置为true,表示取消访问检查

 示例:

public class Demo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {// 获取class字节码文件Class clazz = Class.forName("ReflectDemo2.Student");// 获得所有的构造(只能public修饰)Constructor[] cons1 = clazz.getConstructors();for (Constructor con : cons1) {System.out.println(con);}System.out.println("========");// 获得所有的构造(包含private修饰)Constructor[] cons2 = clazz.getDeclaredConstructors();for (Constructor con : cons2) {System.out.println(con);}System.out.println("========");// 获取指定构造(只能public修饰)// 获取空参构造Constructor con1 = clazz.getConstructor();System.out.println(con1);// 获取指定参数的构造Constructor con2 = clazz.getConstructor(String.class, int.class);System.out.println(con2);System.out.println("========");// 获取指定构造(包含private修饰)Constructor con3 = clazz.getDeclaredConstructor(String.class);System.out.println(con3);}
}public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}private Student(String name) {this.name = name;}protected Student(int age) {this.age = age;}
}

五、获取构造方法并创建对象

//首先要有一个javabean类
public class Student {private String name;private int age;public Student() {}public Student(String name) {this.name = name;}private Student(String name, int age) {this.name = name;this.age = age;}//Getter and Setter………………public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}public class Demo2 {public static void main(String[] args) throws Exception {//1.获取整体的字节码文件对象Class clazz = Class.forName("ReflectDemo2.Student");//2.获取空参的构造方法Constructor con = clazz.getConstructor();//3.利用空参构造方法创建对象Student stu = (Student) con.newInstance();System.out.println(stu);System.out.println("=============================================");//测试类中的代码://需求2://获取带参构造,并创建对象//1.获取整体的字节码文件对象Class clazz = Class.forName("ReflectDemo2.Student");//2.获取有参构造方法Constructor con = clazz.getDeclaredConstructor(String.class, int.class);//3.临时修改构造方法的访问权限(暴力反射)con.setAccessible(true);//4.直接创建对象Student stu = (Student) con.newInstance("zhangsan", 23);System.out.println(stu);}
}

六、获取成员变量并获取值和修改值

  • Field[] getFields():返回所有成员变量对象的数组(只能拿public的) 
  • Field[] getDeclaredFields():返回所有成员变量对象的数组,存在就能拿到     
  • Field getField(String name):返回单个成员变量对象(只能拿public的)       
  • Field getDeclaredField(String name):返回单个成员变量对象,存在就能拿到       

   

Field类种用于创建对象的方法

  • void set(Object obj,Object value):赋值
  • Object get(Object obj):获取值
// 学生类
public class Student {private String name;private int age;public String gender;public String address;public Student() {}public Student(String name, int age, String address) {this.name = name;this.age = age;this.address = address;}public Student(String name, int age, String gender, String address) {this.name = name;this.age = age;this.gender = gender;this.address = address;}// Getter and Setter , toString();………………
}
public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {Student s = new Student("zhangsan",23,"广州");Student ss = new Student("lisi",24,"北京");//需求://利用反射获取成员变量并获取值和修改值//1.获取class对象Class clazz = Class.forName("reflectdemo.Student");//2.获取name成员变量//field就表示name这个属性的对象Field field = clazz.getDeclaredField("name");//临时修饰他的访问权限field.setAccessible(true);//3.设置(修改)name的值//参数一:表示要修改哪个对象的name?//参数二:表示要修改为多少?field.set(s,"wangwu");//3.获取name的值//表示我要获取这个对象的name的值String result = (String)field.get(s);//4.打印结果System.out.println(result);System.out.println(s);System.out.println(ss);}
}

七、获取成员方法并运行

  • Method[] getMethods():返回所有成员方法对象的数组(只能拿public的) 
  • Method[] getDeclaredMethods():返回所有成员方法对象的数组,存在就能拿到     
  • Method getMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象(只能拿public的)       
  • Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象,存在就能拿到           

  • Object invoke(Object obj, Object... args) :运行方法
    • 参数一:用obj对象调用该方法
    • 参数二:调用方法的传递的参数(如果没有就不写)
    • 返回值:方法的返回值(如果没有就不写)
// 学生类
public class Student {private String name;private int age;public String gender;public String address;public Student() {}public Student(String name) {this.name = name;}private Student(String name, int age) {this.name = name;this.age = age;}//Getter and Setter , toString()………………
}
public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {//1.获取字节码文件对象Class clazz = Class.forName("reflectdemo.Student");//2.获取一个对象//需要用这个对象去调用方法Student s = new Student();//3.获取一个指定的方法//参数一:方法名//参数二:参数列表,如果没有可以不写Method eatMethod = clazz.getMethod("eat",String.class);//运行//参数一:表示方法的调用对象//参数二:方法在运行时需要的实际参数//注意点:如果方法有返回值,那么需要接收invoke的结果//如果方法没有返回值,则不需要接收String result = (String) eatMethod.invoke(s, "重庆小面");System.out.println(result);}
}

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

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

相关文章

Python使用multiprocessing模块实现多进程并发处理大数据量

使用multiprocessing模块实现多进程并发地遍历arr1中的值&#xff0c;从arr2中查找是否存在的步骤如下&#xff1a; 导入multiprocessing模块&#xff1a;import multiprocessing 创建查找函数&#xff1a;定义一个函数&#xff0c;用于在arr2中查找arr1的值。可以在这个函数中…

【JVM】Java虚拟机JVM堆内存调优

Java虚拟机JVM堆内存调优 一、了解堆内存结构1.1 JDK 1.7堆内存1.2 JDK 1.8堆内存二、设置合理的堆内存大小(-Xms和-Xmx)三、调整新生代与老年代比例(-XX:NewRatio)四、新生代中Eden区与Survivor区比例(-XX:SurvivorRatio)五、启用并调整并行收集器或并发收集器六、设置垃…

基金撰写过程中是否存在哪些问题?技术路线图如何设计才能吸引评阅专家的目光?

随着社会经济发展和科技进步&#xff0c;基金项目对创新性的要求越来越高。申请人需要提出独特且有前瞻性的研究问题&#xff0c;具备突破性的科学思路和方法。因此&#xff0c;基金项目申请往往需要进行跨学科的技术融合。申请人需要与不同领域结合&#xff0c;形成多学科交叉…

BUUCTF--gyctf_2020_borrowstack1

这是一题栈迁移的题目&#xff0c;先看看保护&#xff1a; 黑盒测试&#xff1a; 用户可输入两次内容&#xff0c;接着看看IDA中具体程序流程&#xff1a; 我们看到溢出内容只有0x10的空间给我们布局&#xff0c;这显然是不足以我们布置rop的。因此肯定就是栈迁移了。迁到什么地…

Vue3地图选点组件

Vue3地图选点组件 <template><div style"width: 100%; height: 500px"><div class"search-container"><el-autocompletev-model"suggestionKeyWord"class"search-container__input"clearable:fetch-suggestion…

后端处理文件上传:对比用Controller层和Service层的优缺点

当涉及文件上传时&#xff0c;有两种主要的处理方式&#xff1a;将文件上传逻辑放在控制器(Controller)层和将文件上传逻辑放在服务(Service)层。以下是这两种方式的优缺点&#xff1a; 将文件上传逻辑放在控制器(Controller)层&#xff1a; 优点&#xff1a; 简化代码结构&a…

error:0308010C:digital envelope routines::unsupported 前端项目错误

直接启动命令中增加&#xff1a; SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service serve

猫咪主食冻干K9、希喂、SC生骨肉冻干哪款好?详细对比测评这三款产品

随着科学养猫的观念深入人心&#xff0c;越来越多的铲屎官开始关注猫咪主食的营养与健康。主食冻干&#xff0c;作为一种模拟猫咪原始猎食的食品&#xff0c;因其高营养保留而受到广大猫奴的喜爱。相比传统的膨化猫粮&#xff0c;主食冻干更符合猫咪的饮食天性&#xff0c;提供…

计算机Java项目|基于SSM实现的在线考试系统

项目编号&#xff1a;L-BS-ZXBS-04 一&#xff0c;环境介绍 语言环境&#xff1a;Java: jdk1.8 数据库&#xff1a;Mysql: mysql5.7 应用服务器&#xff1a;Tomcat: tomcat8.5.31 开发工具&#xff1a;IDEA或eclipse 后台框架&#xff1a;Spring、SpringMVC、MyBatis …

How to talk about your job in English?

笔记原文 Hi, Tim here with another 925English lesson! In today’s lesson we’re going to learn how to talk about your job. There are lots of situations where you meet someone new and you want to tell them about your job. Maybe they ask you about it, or y…

消费REST服务

目录 概述GET资源PUT资源DELETE资源POST资源 概述 Spring应用除了提供对外API之外&#xff0c;同时要对另一个应用的API发起请求。实际上&#xff0c;在微服务领域&#xff0c;这正变得越来越普遍。因此&#xff0c;花点时间研究一下如何使用Spring与RESTAPI交互是非常值得的。…

C语言编译器(C语言编程软件)完全攻略(第五部分:VS2015使用教程(使用VS2015编写C语言程序))

介绍常用C语言编译器的安装、配置和使用。 五、VS2015使用教程&#xff08;使用VS2015编写C语言程序&#xff09; 前面我们给出了一段完整的C语言代码&#xff0c;就是在显示器上输出“C语言中文网”&#xff0c;如下所示&#xff1a; #include <stdio.h> int main() {…

MySQL运维实战(2.3)MySQL的权限体系

作者&#xff1a;俊达 MySQL权限划分 MySQL权限按授权范围可以分为三大类&#xff1a;全局权限、数据库权限和对象权限。 全局权限主要用于管理系统模块&#xff0c;这些权限涵盖了对MySQL服务器整体的操作和管理&#xff0c;与具体的数据库或对象无关&#xff0c;因此在授权…

Leetcode_day01_88合并两个有序数组

Leetcode_day01_88合并两个有序数组 题目描述&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺…

HarmonyOS应用开发学习笔记 包名、icon图标,应用名修改 UIAbility组件介绍、UIAbility启动模式、UIAbility组件基本用法

目前HarmonyOS应用主推的是Stage模型开发 一、Stage模型基本概念 项目描述UIAbility组件UIAbility组件是一种包含UI界面的应用组件&#xff0c;主要用于和用户交互。例如&#xff0c;图库类应用可以在UIAbility组件中展示图片瀑布流&#xff0c;在用户选择某个图片后&#xf…

Hotspot源码解析-第十二章-线程栈保护页

了解保护页&#xff0c;先从几个问题开始吧 1、为什么线程栈有栈帧了&#xff0c;还要有保护页&#xff1f; 答&#xff1a;在操作系统中内存可以看成是一个大数组&#xff0c;这就有一个问题&#xff0c;线程之间可能会互相踩了别人的内存空间&#xff0c;所以栈空间也存在这…

空间域图像增强之直方图均衡的python代码实现——冈萨雷斯数字图像处理

原理 直方图&#xff1a; 图像的直方图是一个图像中像素强度值分布的图表。 对于灰度图像&#xff0c;直方图展示了每个灰度级出现的频率。 直方图均衡步骤&#xff1a; 计算累积分布函数&#xff08;CDF&#xff09;&#xff1a;首先&#xff0c;计算图像的直方图&#xff0…

C语言中一些基本数据类型的典型大小

char&#xff1a;通常是1字节。表示一个字符。int&#xff1a;通常在现代系统中是4字节&#xff08;但这取决于编译器和架构&#xff0c;有时可能是2字节&#xff09;。float&#xff1a;通常是4字节。double&#xff1a;通常是8字节。short 和 short int&#xff1a;通常是2字…

解决:ERROR: Failed building wheel for xxx

解决&#xff1a;ERROR: Failed building wheel for xxx 文章目录 解决&#xff1a;ERROR: Failed building wheel for xxx背景报错问题报错翻译报错原因解决方法参考内容&#xff1a;今天的分享就到此结束了 背景 在使用之前的代码构建环境时&#xff0c;报错&#xff1a;ERRO…

普中STM32-PZ6806L开发板(有点悲伤的故事续-人灯还未了)

简介 继上篇 普中STM32-PZ6806L开发板(有点悲伤的故事) 说到 关于 普中STM32-PZ6806L开发板的LED流水灯也被烧坏掉了&#xff0c;再也无法玩流水灯, 内心充满了只会流水灯的不甘, 流水灯就是单片机的Hello World&#xff0c;怎么能没有呢&#xff1f; 事情发展 好巧不巧想起最近…