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();
}

标签:Java,反射,Reflection
0
投稿

猜你喜欢

  • C#统计字符串里中文汉字个数的方法

    2022-05-12 21:47:10
  • Handler实现线程之间的通信下载文件动态更新进度条

    2021-10-27 16:50:36
  • Android仿百度谷歌搜索自动提示框AutoCompleteTextView简单应用示例

    2022-12-07 07:30:59
  • Mybatis 动态SQL的几种实现方法

    2023-11-10 12:15:15
  • java设计模式之适配器模式

    2021-08-28 09:08:09
  • 详解kotlin中::双冒号的使用

    2022-09-04 10:17:23
  • 解读在C#中winform程序响应键盘事件的详解

    2023-10-08 09:17:00
  • Spring基于AspectJ的AOP开发案例解析

    2021-12-01 01:59:22
  • Android判断用户的网络类型实例讲解(2/3/4G、wifi)

    2022-11-10 23:27:51
  • Android实现自由拖动并显示文字的悬浮框

    2023-06-08 06:30:39
  • C#实现查杀本地与远程进程的方法

    2023-08-10 08:01:30
  • Android自定view画圆效果

    2021-06-05 21:45:52
  • C#实现文件上传及文件下载功能实例代码

    2022-12-13 23:57:23
  • c#反射表达式树模糊搜索示例

    2022-01-09 07:03:31
  • Java的运算符和程序逻辑控制你了解吗

    2023-01-19 10:01:59
  • Java 数据结构中二叉树前中后序遍历非递归的具体实现详解

    2023-02-14 12:51:18
  • C# TextBox控件实现只能输入数字的方法

    2022-03-07 01:57:27
  • Android Intent实现页面跳转的方法示例

    2021-11-08 05:27:22
  • OpenGL Shader实现光照发光体特效

    2022-03-16 18:51:50
  • Java同步函数代码详解

    2022-10-13 23:22:03
  • asp之家 软件编程 m.aspxhome.com