0%
这是一片思考的空间 -- arthinking
Spring 重构&代码整洁之道 软件设计 JVM 并发编程 数据结构与算法 分布式 存储 网络 微服务 设计模式
Java技术栈 - 涉及Java技术体系

Java基础笔记 - 反射机制的介绍和基本的API的使用

关于动态语言:

一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。

Java中的反射机制:

Java中的反射机制指的是在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Java程序可以加载一个运行时才得知名称的Class,并获得其除了方法的定义的完整构造,并生成对象实体,或对其fields设值或调用其methods。

Java反射机制提供的功能:

在运行时判断任意一个对象所属的类在运行时构造任意一个类的对象 在运行时判断任意一个类所具有的成员变量和方法 在运行时调用任意一个对象的方法 生成动态代理

篇外话:

Spring框架中的Ioc使用工厂模式和Java的反射机制;AOP使用了代理模式。

实现Java反射机制的相关类:(位于java.lang.reflect包中)

1
Class  Field  Method  Constructor  Array

Class类介绍:

Class类描述Java程序运行时的所有Classes和interfaces,同时也用来描述enum、array、Java基本数据类型。

生成Class:

当一个class文件被加载或者类加载器的defineClass()被JVM调用时,JVM便自动产生一个Class 对象。

反射机制常用的API

生成Class对象的方法:

① 根据完整类名获取类,调用Class的静态方法forName():

1
Class<?> classType = Class.forName(“java.lang.String”);

② 通过类名获取,使用class语法,这里ReflectionTest为一个类名:

1
Class<?> classType = ReflectionTest.class;

③ 通过对象的getClass()方法获取:

1
2
3
User user = new User();
Class<?> classType = user.getClass();
Class superClass = classType.getSuperclass(); //获取user的父类的Class对象

④ 对于包装类的Class的获取,使用包装类的TYPE语法:

1
Class classType = Integer.Type;

创建反射获取的类的实例的方法:

① 调用Class的newInstance()方法:

1
Object reflectionText = classType.newInstance();

② 通过Class获取构造方法再实例化:

1
Object user2 = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

当Class数组为空时,本质上等价于①,即调用无参构造函数

获取Class对象的方法:

① 获取所有方法:

1
Method[] methods = classType.getMethods();

② 获取指定方法:

1
Method setter = classType.getMethod(methodName, new Class[]{});

其中methodName为方法名,后面的Class数组为方法的参数表。

执行获取的方法:

1
Object result = setter.invoke(reflectionText, new Object[]{"http://www.itzhai.com"});

其中reflectionText为反射获取的类的实例,Object[]为传进方法的参数表。

获取Class对象的域:

获取所有的域,包括公共、保护、默认(包)访问和私有域,但不包括继承的域:

Field[] fields = classType.getDeclaredFields();

获取指定的域,返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段:

1
Field field = classType.getDeclaredField("fieldName");

设置压制访问控制检查,这样就可以获取和设置私有域的值了:

1
field.setAccessible(true);

获取指定的域,只能返回public类型的域:

1
Field field = classType.getField("fieldName");

获取某个对象的域的对应值:

1
2
Field field = classType.getField("fieldName");
field.get(object);

设置某个对象的域的对应值:

1
2
Field field = classType.getField("fieldName");
field.set(obj, "arthinking");

欢迎关注我的其它发布渠道

订阅IT宅
内功修炼
Java技术栈
Java架构杂谈是IT宅精品文章公众号,欢迎订阅:
📄 网络基础知识:两万字长文50+张趣图带你领悟网络编程的内功心法 📄 HTTP发展史:三万长文50+趣图带你领悟web编程的内功心法 📄 HTTP/1.1:可扩展,可靠性,请求应答,无状态,明文传输 📄 HTTP/1.1报文详解:Method,URI,URL,消息头,消息体,状态行 📄 HTTP常用请求头大揭秘 📄 HTTPS:网络安全攻坚战 📄 HTTP/2:网络安全传输的快车道 📄 HTTP/3:让传输效率再一次起飞 📄 高性能网络编程:图解Socket核心内幕以及五大IO模型 📄 高性能网络编程:三分钟短文快速了解信号驱动式IO 📄 高性能网络编程:彻底弄懂IO复用 - IO处理杀手锏,带您深入了解select,poll,epoll 📄 高性能网络编程:异步IO:新时代的IO处理利器 📄 高性能网络编程:网络编程范式 - 高性能服务器就这么回事 📄 高性能网络编程:性能追击 - 万字长文30+图揭秘8大主流服务器程序线程模型
📄 Java内存模型:如果有人给你撕逼Java内存模型,就把这些问题甩给他 📄 一文带你彻底理解同步和锁的本质(干货) 📄 AQS与并发包中锁的通用实现 📄 ReentrantLock介绍与使用 📄 ReentrantReadWriteLock介绍与使用 📄 ReentrantLock的Condition原理解析 📄 如何优雅的中断线程 📄 如何优雅的挂起线程 📄 图解几个好玩的并发辅助工具类 📄 图解BlockingQueue阻塞队列
📄 消息队列那么多,为什么建议深入了解下RabbitMQ? 📄 高并发异步解耦利器:RocketMQ究竟强在哪里? 📄 Kafka必知必会18问:30+图带您看透Kafka
📄 洞悉MySQL底层架构:游走在缓冲与磁盘之间 📄 SQL运行内幕:从执行原理看调优的本质 📄 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法