是一种强大的编程特性,允许在运行时检查、获取和操作类的信息。反射使得可以在运行时动态地创建对象、调用方法、访问字段等,而无需在编译时确定这些操作。
在Java中,可以使用反射来访问类的构造方法
使用Class
对象可以获取类的构造方法。Class
类提供了getConstructor
和getDeclaredConstructor
方法,分别用于获取公共和私有构造方法。
Class> clazz = MyClass.class;
// 获取公共构造方法
Constructor> publicConstructor = clazz.getConstructor(parameterTypes);
// 获取所有声明的构造方法(包括私有)
Constructor>[] constructors = clazz.getDeclaredConstructors();
// 获取私有构造方法
Constructor> privateConstructor = clazz.getDeclaredConstructor(parameterTypes);
创建对象: 使用获取的构造方法对象,可以创建类的实例。
// 对于公共构造方法
MyClass instance1 = (MyClass) publicConstructor.newInstance(args);
// 对于私有构造方法,需要设置可访问性
privateConstructor.setAccessible(true);
MyClass instance2 = (MyClass) privateConstructor.newInstance(args);
例题1
public class MyClass {
private int value;
private MyClass(int value) {
this.value = value;
}
public static MyClass createInstance(int value) {
return new MyClass(value);
}
public int getValue() {
return value;
}
public static void main(String[] args) {
MyClass obj = MyClass.createInstance(42);
System.out.println(obj.getValue());
}
}
使用Class
对象可以获取类的成员变量。Class
类提供了getField
和getDeclaredField
方法,用于获取公共和私有成员变量。
Class> clazz = MyClass.class;
// 获取公共成员变量
Field publicField = clazz.getField("publicFieldName");
// 获取所有声明的成员变量(包括私有)
Field[] fields = clazz.getDeclaredFields();
// 获取私有成员变量
Field privateField = clazz.getDeclaredField("privateFieldName");
访问变量值: 使用获取的Field
对象,可以访问和修改类的成员变量的值。
MyClass instance = new MyClass();
// 获取公共成员变量的值
Object publicValue = publicField.get(instance);
// 获取私有成员变量的值,需要设置可访问性
privateField.setAccessible(true);
Object privateValue = privateField.get(instance);
修改变量值: 使用获取的Field
对象,可以修改类的成员变量的值
// 设置公共成员变量的值
publicField.set(instance, newValue);
// 设置私有成员变量的值,需要设置可访问性
privateField.setAccessible(true);
privateField.set(instance, newValue);
例题2
在Java中,通过反射可以访问类的成员方法。
获取Method对象: 使用Class
对象可以获取类的成员方法。Class
类提供了getMethod
和getDeclaredMethod
方法,用于获取公共和私有成员方法。
Class> clazz = MyClass.class;
// 获取公共成员方法
Method publicMethod = clazz.getMethod("publicMethodName", parameterTypes);
// 获取所有声明的成员方法(包括私有)
Method[] methods = clazz.getDeclaredMethods();
// 获取私有成员方法
Method privateMethod = clazz.getDeclaredMethod("privateMethodName", parameterTypes);
例题3
注解(Annotation)是一种用于为程序元素(类、方法、字段等)添加元数据(metadata)的方式。注解提供了一种在代码中嵌入元信息的机制,这些信息可以被工具、框架或其他程序在运行时或编译时进行解析和处理。
元数据添加: 注解允许开发者在源代码中嵌入元数据,以描述程序元素的附加信息。这些信息可以包括作者、版本、依赖关系、用途说明等。
编译时处理: 注解可以被编译器处理,以在编译时执行特定的操作。例如,常见的注解处理器包括生成代码、验证代码规范、生成文档等。
自定义注解: Java允许开发者定义自己的注解,通过@interface
关键字进行定义。自定义注解可以包含元素,这些元素可以有默认值,也可以是特定的数据类型。
Java中,可以使用@interface
关键字来定义自定义的注解类型
要访问注解信息,可以使用反射机制。通过反射,你可以在运行时获取类、方法、字段等元素上的注解,并检索注解的元素值。
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
// 自定义注解
@interface MyAnnotation {
String value() default "";
int count() default 0;
}
// 使用注解的类
public class MyClass {
// 应用自定义注解
@MyAnnotation(value = "Hello", count = 42)
public void myMethod() {
// method implementation
}
public static void main(String[] args) {
// 获取MyClass类中的myMethod方法上的注解信息
try {
Class> clazz = MyClass.class;
Method method = clazz.getMethod("myMethod");
// 获取方法上的所有注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof MyAnnotation) {
// 强制转换为自定义注解类型
MyAnnotation myAnnotation = (MyAnnotation) annotation;
// 访问注解的元素
String value = myAnnotation.value();
int count = myAnnotation.count();
System.out.println("Value: " + value);
System.out.println("Count: " + count);
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
课上的例题
结果