网站首页 > 精选教程 正文
相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有个开源框架jOOR相信很多人都用过,不过我们还是要学习反射的基础语法,这样才能自己写出优秀的框架,当然这里所讲的反射技术,是学习Android插件化技术、Hook技术等必不可少的!
概述
Java 反射是可以让我们在运行时获取类的方法、属性、父类、接口等类的内部信息的机制。也就是说,反射本质上是一个“反着来”的过程。我们通过new创建一个类的实例时,实际上是由Java虚拟机根据这个类的Class对象在运行时构建出来的,而反射是通过一个类的Class对象来获取它的定义信息,从而我们可以访问到它的属性、方法,知道这个类的父类、实现了哪些接口等信息。
何为反射?
Java的 反射机制 是在运行状态中,对于任意一个类,都能够 知道这个类的所有属性和方法 ;对于任意一个对象,都能够 调用它的任意一个方法和属性 ;这种 动态获取的信息以及动态调用对象的方法的功能 称为 Java 语言的反射机制。
简而言之,只要你给我一个 .class ——类的名字,我就能通过反射获取到类的属性和方法。
反射是很多高级技术的基础,Java 中的注解、动态代理,各种框架注入 Spring 、 MyBatis 等都用到了反射技术。
反射机制能做什么
1. 在运行时判断一个对象所属的类
2. 在运行时可以构造任意一个类的对象
3. 在运行时可以任意判断一个类所包含的成员变量和方法
4. 在运行时可以任意调用一个对象的方法
5. 生成动态代理
Class类
我们知道使用javac能够将.java文件编译为.class文件,这个.class文件包含了我们对类的原始定义信息(父类、接口、构造器、属性、方法等)。.class文件在运行时会被ClassLoader加载到Java虚拟机(JVM)中,当一个.class文件被加载后,JVM会为之生成一个Class对象,我们在程序中通过new实例化的对象实际上是在运行时根据相应的Class对象构造出来的。确切的说,这个Class对象实际上是java.lang.Class泛型类的一个实例,比如Class对象即为一个封装了MyClass类的定义信息的Class实例。由于java.lang.Class类不存在公有构造器,因此我们不能直接实例化这个类,我们可以通过以下方法获取一个Class对象。
Class 类在 JDK 中的定义
public final class Class<T>
extends Object
implements Serializable, GenericDeclaration, Type, AnnotatedElement
复制代码
类 Class 的实例表示运行中的 Java 应用程序中的类和接口。
枚举 是一种类,注释 是一种接口。
每个 数组 也属于一个类,这个类反映为一个 类对象 ,由具有相同元素类型和维数的所有数组共享。
原始Java类型(布尔型、字节型、char型、short型、int型、long型、float型和double型)和关键字void也被表示为类对象。
类的加载过程
Class类的实例表示正在运行的Java应用程序中的类和接口。每个类只会产生一个Class对象,在类加载的时候自动创建
获取Class类的三种方式
1 通过 class.forname()来获取Class对象
Class clazz = Class.forName("com.mashibing.entity.Emp");
System.out.println(clazz.getPackage());
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
System.out.println(clazz.getCanonicalName());
2 通过类名.class来获取Class对象
Class<Emp> clazz = Emp.class;
System.out.println(clazz.getPackage());
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
System.out.println(clazz.getCanonicalName());
3 通过对象的getClass()来获取Class对象
Class clazz = new Emp().getClass();
System.out.println(clazz.getPackage());
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
System.out.println(clazz.getCanonicalName());
4如果是一个基本数据类型,那么可以通过Type的方式来获取Class对象
Class type = Integer.TYPE;
System.out.println(type.getName());
System.out.println(type.getCanonicalName());
反射常用到的API
- 获取类的构造方法:
- public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException public Constructor<?>[] getConstructors() throws SecurityException 复制代码
- 获取类的成员变量
- public Field getField(String name) throws NoSuchFieldException, SecurityException public Field[] getFields() throws SecurityException 复制代码
- 获取类的方法
- public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
反射在 Spring 中的应用举例
反射在众多框架中都有普遍的应用。比如 Spring IOC 容器帮我们实例化众多的bean,下面我们简单模拟一下 反射 在其中起到的作用。
此处使用的案例接这篇:【设计模式】代理模式那些事儿:静态代理,动态代理,JDK的动态代理,cglib,Spring AOP
Spring 配置文件:
<bean id="pony" class="com.xblzer.dp.proxy.springaop.Pony"></bean>
复制代码
使用的时候直接这样就能拿到定义的类了:
ApplicationContext ctx = new ClassPathXmlApplicationContext("app_aop.xml");
Pony pony = (Pony) ctx.getBean("pony");
复制代码
那么是怎么做到的呢?就是通过 反射 。
Spring 通过配置文件实例化对象,并将其放到容器的过程大概就是(模拟):
最后希望大家能从文章中得到帮助获得收获,也可以评论出你想看哪方面的技术。文章会持续更新,希望能帮助到大家,哪怕是让你灵光一现。喜欢的朋友可以点点赞和关注,也可以分享出去让更多的人看见,一起努力一起进步!
猜你喜欢
- 2024-11-13 十年Java工程师写下的Java反射使用总结
- 2024-11-13 一起来了解Java中的反射 java反射的步骤原理
- 2024-11-13 Java基础:反射机制,你用得多吗 java反射机制有什么用
- 2024-11-13 每日一点涨薪小知识-JAVA反射 java反射的理解
- 2024-11-13 Java反射的原理以及应用场景 java中反射的实际用法
- 2024-11-13 浅谈java中的反射(恭喜FPX) java里的反射是什么
- 2024-11-13 实操讲解Java的反射机制,你要是再看不懂,神仙都没救了
- 2024-11-13 两分钟学会Java反射 java 反射
- 2024-11-13 三石说:java基础 之 反射 java反射的基石
- 2024-11-13 0202年了,还有人不懂Java反射机制?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)