数据结构 Java数据结构 --- 反射
文章目录
- 反射
- 1. 反射的定义
- 2. 反射的用途
- 3. 反射基本信息
- 4. 反射相关的类
- 4.1 Class类
- 4.1.1 Class类中的相关方法
- 常用获得类相关的方法
- 常用获得类中属性相关的方法(以下方法返回值为Field相关)
- 获得类中注解相关的方法
- 获得类中构造器相关的方法(以下方法返回值为Constructor相关)
- 获得类中方法相关的方法(以下方法返回值为Method相关)
- 4.2 反射示例
- 4.2.1 获得Class对象的三种方式
- 4.2.2 反射的使用
- 4.2.2.1 通过 Class 类的newInstance方法 获取 学生实例
- 4.2.2.2 反射所有的私有的构造方法
- 4.2.2.3 反射私有或者公开的属性
- 4.2.2.4 反射私有方法
- 5. 反射优点和缺点
- 优点:
- 缺点:
反射
1. 反射的定义
Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。
2. 反射的用途
1、在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法 。
2、反射最重要的用途就是开发各种通用框架,比如在spring中,我们将所有的类Bean交给spring容器管理,无论是XML配置Bean还是注解配置,当我们从容器中获取Bean来依赖注入时,容器会读取配置,而配置中给的就是类
的信息,spring根据这些信息,需要创建那些Bean,spring就动态的创建这些类。
3. 反射基本信息
Java程序中许多对象在运行时会出现两种类型:运行时类型(RTTI)和编译时类型,例如Person p = new Student();
这句代码中p在编译时类型为Person,运行时类型为Student。程序需要在运行时发现对象和类的真实
信息。而通过使用反射程序就能判断出该对象和类属于哪些类。
4. 反射相关的类
类名 | 用途 |
---|---|
Class类 | 代表类的实体,在运行的Java应用程序中表示类和接口 |
Field类 | 代表类的成员变量/类的属性 |
Method类 | 代表类的方法 |
Constructor类 | 代表类的构造方法 |
4.1 Class类
代表类的实体,在运行的Java应用程序中表示类和接口 .
Java文件被编译后,生成了.class
文件,JVM此时就要去解读.class
文件 ,被编译后的Java文件.class
也被JVM解析为一个对象,这个对象就是 java.lang.Class
.这样当程序在运行时,每个类就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类 .
4.1.1 Class类中的相关方法
常用获得类相关的方法
方法 | 用途 |
---|---|
getClassLoader() | 获得类的加载器 |
getDeclaredClasses() | 返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的) |
forName(String className) | 根据类名返回类的对象 |
newInstance() | 创建类的实例 |
getName() | 获得类的完整路径名字 |
常用获得类中属性相关的方法(以下方法返回值为Field相关)
方法 | 用途 |
---|---|
getField(String name) | 获得某个公有的属性对象 |
getFields() | 获得所有公有的属性对象 |
getDeclaredField(String name) | 获得某个属性对象 |
getDeclaredFields() | 获得所有属性对象 |
获得类中注解相关的方法
方法 | 用途 |
---|---|
getAnnotation(Class annotationClass) | 返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() | 返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class annotationClass) | 返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() | 返回该类所有的注解对象 |
获得类中构造器相关的方法(以下方法返回值为Constructor相关)
方法 | 用途 |
---|---|
getConstructor(Class…<?> parameterTypes) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class…<?> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
获得类中方法相关的方法(以下方法返回值为Method相关)
方法 | 用途 |
---|---|
getMethod(String name, Class…<?> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class…<?> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
4.2 反射示例
4.2.1 获得Class对象的三种方式
在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息。
第一种,使用 Class.forName(“类的全路径名”); 静态方法。
前提:已明确类的全路径名。
第二种,使用 .class 方法。
说明:仅适合在编译前就已经明确要操作的 Class
第三种,使用类对象的 getClass() 方法
class Student{//私有属性nameprivate String name = "bit";//公有属性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 +'}';}
}
public class Test {public static void main(String[] args) throws ClassNotFoundException {// 第一种,使用 Class.forName("类的全路径名"); 静态方法。Class<?> c1 = Class.forName("Student");// 第二种,使用 .class 方法。Class<?> c2 = Student.class;// 第三种,使用类对象的 getClass() 方法 (不常用)Student student = new Student();Class<?> c3 = student.getClass();System.out.println(c1 == c2); // trueSystem.out.println(c1 == c3); // trueSystem.out.println(c2 == c3); // true}
}
4.2.2 反射的使用
注意:所有和反射相关的包都在import java.lang.reflect
包下面。
4.2.2.1 通过 Class 类的newInstance方法 获取 学生实例
/*** 通过 Class 类的newInstance方法 获取 学生实例*/public static void reflectNewInstance() {try {Class<?> c1 = Class.forName("Student");Student student = (Student) c1.newInstance();System.out.println(student);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
4.2.2.2 反射所有的私有的构造方法
public static void reflectPrivateConstructor() {try {Class<?> c1 = Class.forName("Student");Constructor<?> constructor = c1.getDeclaredConstructor(String.class,int.class);//传的时候要 .classconstructor.setAccessible(true); // 因为是私有的 所以要改为trueStudent student = (Student) constructor.newInstance("niubi",80);System.out.println(student);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
4.2.2.3 反射私有或者公开的属性
public static void reflectPrivateField() {try {Class<?> c1 = Class.forName("Student");Student student = (Student) c1.newInstance();Field field = c1.getDeclaredField("name");field.setAccessible(true);field.set(student,"wang wu");System.out.println(student);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();}}
4.2.2.4 反射私有方法
public static void reflectPrivateMethod() {try {Class<?> c1 = Class.forName("Student");Student student = (Student) c1.newInstance();Method method = c1.getDeclaredMethod("function", String.class);method.setAccessible(true);method.invoke(student,"牛逼 牛逼 牛逼 私有的方法");} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
5. 反射优点和缺点
优点:
- 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
- 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
- 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。
缺点:
- 使用反射会有效率问题。会导致程序效率降低。
- 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。
数据结构 Java数据结构 --- 反射相关推荐
- 数据结构 Java数据结构 --- Lambda表达式
文章目录 Lambda表达式 1. Lambda表达式的背景 1.1 Lambda表达式的语法 1.2 函数式接口 2. Lambda表达式的基本使用 2.1 无返回值无参数 2.2 无返回值一个参数 ...
- 冒泡排序算法(思路分析) [数据结构][Java]
冒泡排序算法(思路分析) 基本介绍: 冒泡排序(Bubble Sorting)的基本思想是: 通过对 "待排序序列" 从前向后一次比较相邻元素的值,若发现逆序则交换,使值较大的元素 ...
- 希尔排序算法(思路分析) [数据结构][Java]
希尔排序算法(思路分析) 希尔排序也称之为: 缩小增量排序 希尔排序提出的背景: 因为简单插入排序中存在一些问题( 这里我们以升序排序为例 ): 当我们要待插入的数值比较小时后移的次数明显增多,对效率 ...
- java队列_如何彻底搞懂 Java 数据结构?CSDN 博文精选
作者 | 张振华.Jack 责编 | 郭芮 出品 | CSDN 博客 本文和大家一起来重温<Java数据结构>经典之作. Java数据结构 要理解Java数据结构,必须能清楚何为数据结构? ...
- Java 数据结构与算法系列之冒泡排序
一.前言 相信大部分同学都已经学过数据结构与算法这门课了,并且我们可能都会发现一个现象就是我们所学过的数据结构与算法类的书籍基本都是使用 C 语言来写的,好像没见过使用 Java 写的数据结构与算法. ...
- Java数据结构与算法——树(基本概念,很重要)
声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 有网友私信我,期待我的下一篇数据结构.非常荣幸文章被认可,也非常感谢你们的监督. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督 ...
- java数据结构 队列_Java数据结构与算法[原创]——队列
声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本文介绍数据结构中的队列(queue)的概念.存储结构.队列的特点,文末给出ja ...
- java 结构数据结构_Java 数据结构
Java 数据结构 Java工具包提供了强大的数据结构.在Java中的数据结构主要包括以下几种接口和类: 枚举(Enumeration) 位集合(BitSet) 向量(Vector) 栈(Stack) ...
- 数据结构 python的书推荐-java数据结构书一般推荐看什么好?
想要学习java的各种数据结构,一本良好的书籍会让你受益匪浅,本文就来推荐一些学习java数据结构适合看的书. 一.入门推荐 因为是入门,所以我们先不要求实现,阅读一些通过图片,打比方等通俗易懂的方法 ...
- Java数据结构与算法——插入排序
声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本篇文章介绍排序算法中插入排序算法,包括插入排序的思路,适用场景,性能分析,ja ...
最新文章
- js 文本反向排列显示
- r语言手动算两个C指数p值,如何用R语言进行Pvalue显著性标记?
- Python需求增速达174%,AI人才缺口仍超百万!这份来自2017年的实际招聘数据如是说
- 来自顶尖JAVA程序猿的焦虑,拒绝中年危机,唯有一生力学笃行
- python目录操作shutil
- 对象数组空指针异常说明——C#中使用对象数组必须分别为其开辟空间
- oozie案例——自定义MapReduce workflow
- hdu 2612 FindAWay 两点BFS
- 荣耀赵明:电视开关机广告不符合商业逻辑 用户需享受收益分成
- 求python一个类与对象的代码_Python基础系列(五)类和对象,让你更懂你的python代码...
- Nginx源码分析 - Event事件篇 - Nginx的Event事件模块概览(17)
- 计算机没wps云档怎么办,WPS云空间多大?WPS云文档空间已经用满怎么办?删数据或买VIP-太平洋电脑网...
- elasticsearch报错java.lang.IllegalStateException: failed to obtain node locks, tried [[/usr/local/elas
- 五年从程序员到架构师 架构师进阶之路
- 【小技巧】利用matlab进行批量文件下载并解压
- Keil代码折来叠功能显示与隐藏!!!
- 计算机管理创建超级用户,win10系统怎么创建超级管理员账户
- numpy 三角函数 sin()、cos()、tan() 反三角函数arcsin,arccos,arctan numpy.degrees()
- 记一次从 git pull 出现 Untracked FilesPervent Merge
- 【C++】VAL树的旋转(左单旋、右单旋、双旋)