Java反射机制

反射机制简介

反射是Java提供的一种在运行时检查、修改程序结构和行为的能力,它允许程序在运行时获取类的信息并操作类的属性和方法。

反射的基本概念

// 获取Class对象的方式 // 1. 通过类名 Class clazz1 = String.class; // 2. 通过对象 String str = "Hello"; Class clazz2 = str.getClass(); // 3. 通过类名字符串 try { Class clazz3 = Class.forName("java.lang.String"); } catch (ClassNotFoundException e) { e.printStackTrace(); }

获取类信息

通过反射可以获取类的各种信息,包括类名、包名、父类、接口等。

public class ReflectionDemo { public static void main(String[] args) { Class clazz = String.class; // 获取类名 System.out.println("类名:" + clazz.getName()); System.out.println("简单类名:" + clazz.getSimpleName()); // 获取包名 Package pkg = clazz.getPackage(); System.out.println("包名:" + pkg.getName()); // 获取父类 Class superClass = clazz.getSuperclass(); System.out.println("父类:" + superClass.getName()); // 获取实现的接口 Class[] interfaces = clazz.getInterfaces(); for (Class iface : interfaces) { System.out.println("接口:" + iface.getName()); } } }

构造方法

通过反射可以获取和调用类的构造方法。

public class ConstructorDemo { public static void main(String[] args) throws Exception { Class clazz = String.class; // 获取所有公共构造方法 Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("构造方法:" + constructor); } // 获取指定参数类型的构造方法 Constructor constructor = clazz.getConstructor(byte[].class); // 创建实例 byte[] bytes = "Hello".getBytes(); String str = (String) constructor.newInstance(bytes); System.out.println("创建的字符串:" + str); } }

字段

通过反射可以获取和修改类的字段值。

public class FieldDemo { public static void main(String[] args) throws Exception { Class clazz = Person.class; // 获取所有公共字段 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println("字段:" + field.getName()); } // 获取指定名称的字段 Field nameField = clazz.getField("name"); // 创建实例并设置字段值 Person person = new Person(); nameField.set(person, "张三"); System.out.println("姓名:" + nameField.get(person)); // 获取私有字段 Field ageField = clazz.getDeclaredField("age"); ageField.setAccessible(true); ageField.set(person, 25); System.out.println("年龄:" + ageField.get(person)); } }

方法

通过反射可以获取和调用类的方法。

public class MethodDemo { public static void main(String[] args) throws Exception { Class clazz = String.class; // 获取所有公共方法 Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println("方法:" + method.getName()); } // 获取指定名称和参数类型的方法 Method substring = clazz.getMethod("substring", int.class, int.class); // 调用方法 String str = "Hello World"; String result = (String) substring.invoke(str, 0, 5); System.out.println("子字符串:" + result); // 调用私有方法 Method privateMethod = clazz.getDeclaredMethod("privateMethod"); privateMethod.setAccessible(true); privateMethod.invoke(str); } }

注解

通过反射可以获取和处理类的注解信息。

// 自定义注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation { String value() default ""; } // 使用注解 @MyAnnotation("测试类") public class AnnotatedClass { // 类的内容 } // 获取注解信息 public class AnnotationDemo { public static void main(String[] args) { Class clazz = AnnotatedClass.class; // 获取类上的注解 MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class); if (annotation != null) { System.out.println("注解值:" + annotation.value()); } // 获取所有注解 Annotation[] annotations = clazz.getAnnotations(); for (Annotation ann : annotations) { System.out.println("注解:" + ann.annotationType().getName()); } } }

动态代理

Java反射机制支持动态代理,可以在运行时创建代理类。

// 接口 public interface UserService { void addUser(String name); void deleteUser(String name); } // 实现类 public class UserServiceImpl implements UserService { @Override public void addUser(String name) { System.out.println("添加用户:" + name); } @Override public void deleteUser(String name) { System.out.println("删除用户:" + name); } } // 代理处理器 public class LoggingHandler implements InvocationHandler { private Object target; public LoggingHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用方法:" + method.getName()); Object result = method.invoke(target, args); System.out.println("方法调用完成"); return result; } } // 使用动态代理 public class ProxyDemo { public static void main(String[] args) { UserService userService = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new LoggingHandler(userService) ); proxy.addUser("张三"); proxy.deleteUser("李四"); } }

实践练习

练习1:实现一个简单的对象复制器

public class ObjectCopier {
    public static  T copy(T source) {
        // 使用反射实现对象复制
        // 复制所有字段的值
    }
}