反射机制(简单版)
反射:动态引入类、动态调用实例的成员函数、成员变量等。
常用API:
(1) java.lang.Class
(2) java.lang.reflect.Method
(3) java.lang.reflect.Field
(4) java.lang.reflect.Constructor
举例
package org.yxc;public class Calculator {public String name;public Calculator() {}public Calculator(String name) {this.name = name;}public int add(int a, int b) {return a + b;}
}
package org.yxc;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Main {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {Class<?> cls = Class.forName("org.yxc.Calculator");Object o = cls.newInstance();Method method = cls.getMethod("add", int.class, int.class);int res = (int)method.invoke(o, 3, 4);System.out.println(res);Field field = cls.getField("name");field.set(o, "My Calculator!");System.out.println(field.get(o));Constructor<?> constructor = cls.getConstructor(String.class);Object new_o = constructor.newInstance("New Calculator!");System.out.println(new_o);}
}
这段代码展示了如何通过反射机制动态地加载类、调用方法、访问字段和调用构造方法。具体解释如下:
1. 引入反射库
import java.lang.reflect.*;
代码中使用了ClassNotFoundException
、InstantiationException
、IllegalAccessException
、NoSuchMethodException
、InvocationTargetException
等异常处理,这些与反射库中的java.lang.reflect
类息息相关。
2、加载类
Class<?> cls = Class.forName("org.yxc.Calculator");
Class.forName("org.yxc.Calculator")
:根据类名字符串加载类org.yxc.Calculator
。- 该方法会返回一个
Class<?>
对象,表示指定的类。
3、实例化对象
Object o = cls.newInstance();
cls.newInstance()
:调用类的无参构造函数创建一个Calculator
的实例。- 返回值是一个
Object
类型,表示类的实例。
4、调用方法
Method method = cls.getMethod("add", int.class, int.class);
int res = (int)method.invoke(o, 3, 4);
System.out.println(res);
cls.getMethod("add", int.class, int.class)
:获取名称为add
且参数类型为两个int
的公共方法。method.invoke(o, 3, 4)
:调用该方法,传入实例对象o
和参数3, 4
。返回结果存入res
。- 最后打印结果
res
。
5、访问字段
Field field = cls.getField("name");
field.set(o, "My Calculator!");
System.out.println(field.get(o));
cls.getField("name")
:获取名为name
的公共字段。field.set(o, "My Calculator!")
:设置对象o
的name
字段的值为"My Calculator!"
。field.get(o)
:获取对象o
的name
字段的值,并打印出来。
6、调用构造函数
Constructor<?> constructor = cls.getConstructor(String.class);
Object new_o = constructor.newInstance("New Calculator!");
System.out.println(new_o);
cls.getConstructor(String.class)
:获取参数类型为String
的公共构造函数。constructor.newInstance("New Calculator!")
:使用该构造函数创建一个新实例,传入参数"New Calculator!"
。System.out.println(new_o)
:打印新创建的实例。
这段代码展示了 Java 反射的基本操作,涉及动态加载类、调用方法、访问字段以及调用构造函数。反射可以在运行时处理类的结构,非常灵活,但也可能带来性能开销和安全性问题。