Java反射机制(Reflection)浅析
作者:junjie 发布时间:2023-04-17 14:35:56
Reflection也就是反射,是Java语言的一个重要特征,我们知道,在使用一个类之前,我们往往都已经创建好它了,比如创建一个类文件,然后再写些属性、方法等,也就是这种类是静态的,但反射机制却允许你动态地创建一个类。除了动态地创建一个类外,我们还能动态地获取同类对象的数据,并将这些数据赋给新创建的类,这有点类似克隆复制。在很多时候,我们都需要这种动态创建类的特征,比如在处理一些业务,但这些业务却又稍有区别的时候,往往对应着多个类,在处理的时候,我们就要根据不同的业务处理来调用不同的类,这个时候反射机制就派上用场了。
以下是JDK API中关于软件包java.lang.reflect的描述:
提供类和接口,以获取关于类和对象的反射信息。在安全限制内,反射允许编程访问关于加载类的字段、方法和构造方法的信息,并允许使用反射字段、方法和构造方法对对象上的基本对等项进行操作。
如果必需的 ReflectPermission 可用,则 AccessibleObject 允许抑制访问检查。
Arrays 提供动态创建和访问数组的静态方法。
此包中的类以及 java.lang.Class 可以适应以下应用程序的需要:调试程序、解释程序、对象检查程序、类浏览程序,以及服务(比如,Object Serialization 和 JavaBean,它们需要访问目标对象(基于其运行时类)的公共成员或给定类声明的成员)。
下面通过两个简单例子来说明反射的用法,首先先创建一个Person类:
package test;
public class Person {
private int age;
private String name = "";
private String[] arr = new String[2];
public Person(){}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getArr() {
return arr;
}
public void setArr(String[] arr) {
this.arr = arr;
}
}
实例1:得到Person类的属性及方法信息
private static void testSimpleReflect(){
String className = "test.Person";
try {
Class c = Class.forName(className);
Field[] fields = c.getDeclaredFields();
Method[] m = c.getDeclaredMethods();
for (Field field : fields){
System.out.println(field.getName());
}
for (Method method : m){
System.out.println(m.getClass());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
这种是非常简单的,通过类所在包路径来得到一个类,在实际的工作中,也是使用最多的。
实例2:对象复制
@SuppressWarnings("unchecked")
public static Object copy(Object object) throws Exception {
// 获得对象类型
Class classType = object.getClass();
System.out.println("" + classType.getName()); // 通过默认构造方法创建一个新的对象
Object objectCopy = classType.getConstructor(new Class[] {})
.newInstance(new Object[] {}); // 获得对象的所有属性
Field fields[] = classType.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
String firstLetter = fieldName.substring(0, 1).toUpperCase(); // 获得和属性对应的getXXX()方法的名字
String getMethodName = "get" + firstLetter + fieldName.substring(1); // 获得和属性对应的setXXX()方法的名字
String setMethodName = "set" + firstLetter + fieldName.substring(1); // 获得和属性对应的getXXX()方法
Method getMethod = classType.getMethod(getMethodName,
new Class[] {}); // 获得和属性对应的setXXX()方法
Method setMethod = classType.getMethod(setMethodName,
new Class[] { field.getType() }); // 调用原对象的getXXX()方法
Object value = getMethod.invoke(object, new Object[] {});
System.out.println(fieldName + ":" + value); // 调用拷贝对象的setXXX()方法
setMethod.invoke(objectCopy, new Object[] { value });
}
return objectCopy;
}
利用反射来实现对象的复制,我们通常不用自己这么干,因为开源系统BeanUtils已经替我们做好对象拷贝的封装了,我们直接调用它的方法即可,但值得注意的是,BeanUtils也是基于反射机制来做的封装
下面是一调用:
public static void main(String[] args){
Person person = new Person("tom",22);
String[] strs = new String[]{"a","b"};
person.setArr(strs);
try {
Person p = (Person)copy(person);
System.out.println(p.getName()+">>"+p.getAge());
for (String str : p.getArr()){
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
}
// testSimpleReflect();
}


猜你喜欢
- Android中广播(BroadcastReceiver)的详细讲解.1. BroadcastReceiver的注册过程: (1).广播消息
- CamShift算法全称是“Continuously Adaptive Mean-Shift”(连续的自适应MeanShift算法),是对M
- 为了防止测试妹子或者用户频繁点击某个按钮,导致程序在短时间内进行多次数据提交or数据处理,那到时候就比较坑了~那么如何有效避免这种情况的发生
- 具体代码如下所示:private string GetWeekName(DayOfWeek week) { &nb
- 前言:函数式编程是一种编程范式,其中程序是通过应用和组合函数来构造的。它是一种声明式编程范式,其中函数定义是表达式树,每个表达式树返回一个值
- 我就废话不多说了,大家还是直接看代码吧~List<Order> list = new ArrayList<User>
- #region 监视文件夹的变化
- 前言#Android 7.0已经发布很久了,虽然市场份额还不是很高,但是流行起来都是早晚的事,所以适配Android 7.0刻不容缓。And
- 一、导航栏UINavigationBar1、导航栏的使用在iOS开发中,我们通常会使用导航控制器,导航控制器中封装了一个UINavigati
- 本篇文章基于redisson-3.17.6版本源码进行分析一、主从redis架构中分布式锁存在的问题1、线程A从主redis中请求一个分布式
- notification是一种让你的应用程序在没有开启情况下或在后台运行警示用户。它是看不见的程序组件(Broadcast Receiver
- 本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序的数据缓存功能。在Spring Boot应用程序中,我们可
- 序列帧动画经常用到,最直接的方式就是用Animation录制。但某些情况下这种方式并不是太友好,需要靠代码的方式进行序列帧动画的实现。代码实
- Java 目前已经出到13的版本,但是国内大部分公司应该都停留在 Java 8 的版本(不敢承担升级带来的风险)。在Java8中给我们带来了
- 这篇文章主要介绍了springboot配置aop切面日志打印过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- Class:EcanRMB.cs using System; using System.Collections.Gen
- 本文实例为大家分享了SpringBoot使用POI进行Excel下载的具体代码,供大家参考,具体内容如下使用poi处理Excel特别方便,此
- Pom依赖<parent> <groupId>org.springframework.bo
- Join子句一、简介使用join子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联,唯一的要求是每个源中的元素需要共享某个可以
- response.setHeader设置下载文件名无效response.setContentType("application/o