本文共 9956 字,大约阅读时间需要 33 分钟。
反射是Java语言中的一个强大特性,允许开发者在运行时对类、对象、字段、方法等进行动态操作。它不仅可以用来检查对象的类型,还能动态加载类、创建对象、访问属性和方法等。反射机制在Java应用开发中具有重要的功能,广泛应用于代码执行、测试、调试等多个方面。本文将详细介绍Java反射机制的核心类及其常用方法,并通过实际案例展示反射的应用场景。
反射机制的核心在于Class类,它是Java中表示类和接口的实体。在反射中,Class类提供了丰富的方法,用于动态操作类、字段、方法等。反射的主要功能包括:
在Java反射中,Class类是最核心的类,其余如Field、Method、Constructor等都属于Class类的子类。以下是这些核心类的主要功能:
Class类用于表示类和接口,在反射中可以通过Class类完成以下操作:
forName(String className)
方法加载指定类名的类。getName()
、getClasses()
、getSuperclass()
等方法获取。getMethod()
、getDeclaredMethod()
等方法获取方法,通过getField()
、getDeclaredField()
等方法获取字段。Field类用于反射类的字段(即成员变量)。主要方法包括:
get(Object obj)
、getDeclaredField(String name)
。set(Object obj, Object value)
。equals(Object obj)
。Method类用于反射类的方法,主要方法包括:
invoke(Object obj, Object... args)
。getMethod(String name, Class<?>... parameterTypes)
、getDeclaredMethod(String name, Class<?>... parameterTypes)
。Constructor类用于反射类的构造方法,主要方法包括:
newInstance(Object... initargs)
。getDeclaredConstructor(Class<?>... parameterTypes)
、getConstructor(Class<?>... parameterTypes)
。Class类是反射的核心类,其方法种类繁多,主要包括以下几类:
getName()
:返回类的全名。getClasses()
:返回当前类的所有公开类和接口。getDeclaredClasses()
:返回当前类的所有类和接口(包括非公开的)。getMethod(String name, Class<?>... parameterTypes)
:获取某个公开方法。getMethods()
:获取当前类的所有公开方法。getDeclaredMethod(String name, Class<?>... parameterTypes)
:获取某个方法(包括非公开的)。getDeclaredMethods()
:获取当前类的所有方法(包括非公开的)。getField(String name)
:获取某个公开字段。getFields()
:获取当前类的所有公开字段。getDeclaredField(String name)
:获取某个字段(包括非公开的)。getDeclaredFields()
:获取当前类的所有字段(包括非公开的)。getAnnotation(Class<? extends Annotation> annotationClass)
:获取某个注解。getAnnotations()
:获取当前类的所有注解。getDeclaredAnnotation(Class<? extends Annotation> annotationClass)
:获取某个注解(包括非公开的)。getDeclaredAnnotations()
:获取当前类的所有注解(包括非公开的)。newInstance(Object... initargs)
:根据参数创建类的实例。getPackage()
:获取类的包。isAnnotation()
:判断是否是注解类型。isArray()
:判断是否是数组类。isEnum()
:判断是否是枚举类。Field类用于反射字段,其主要方法包括:
get(Object obj)
:获取指定对象的字段值。getDeclaredField(String name)
:获取指定字段名的字段。set(Object obj, Object value)
:设置指定对象的字段值。equals(Object obj)
:判断两个字段是否相等。Method类用于反射方法,其主要方法包括:
invoke(Object obj, Object... args)
:调用指定对象的方法。getMethod(String name, Class<?>... parameterTypes)
:获取某个方法。getDeclaredMethod(String name, Class<?>... parameterTypes)
:获取某个方法(包括非公开的)。Constructor类用于反射构造方法,其主要方法包括:
newInstance(Object... initargs)
:根据参数创建类实例。getDeclaredConstructor(Class<?>... parameterTypes)
:获取特定构造方法。getConstructor(Class<?>... parameterTypes)
:获取公开的构造方法。为了更好地理解反射机制,我们可以通过一个具体的例子——Book
类,展示反射的基本操作。以下是Book
类的代码:
public class Book { private final static String TAG = "BookTag"; private String name; private String author; public Book() { } private Book(String name, String author) { this.name = name; this.author = author; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } private String declaredMethod(int index) { String string = null; switch (index) { case 0: string = "I am declaredMethod 1 !"; break; case 1: string = "I am declaredMethod 2 !"; break; default: string = "I am declaredMethod 1 !"; } return string; }}
接下来,我们可以通过反射创建Book
对象,并对其进行操作。以下是ReflectClass
类的代码:
public class ReflectClass { private final static String TAG = "peter.log.ReflectClass"; // 创建对象 public static void reflectNewInstance() { try { Class classBook = Class.forName("com.android.peter.reflectdemo.Book"); Object objectBook = classBook.newInstance(); Book book = (Book) objectBook; book.setName("Android进阶之光"); book.setAuthor("刘望舒"); Log.d(TAG, "reflectNewInstance book = " + book.toString()); } catch (Exception ex) { ex.printStackTrace(); } } // 反射私有的构造方法 public static void reflectPrivateConstructor() { try { Class classBook = Class.forName("com.android.peter.reflectdemo.Book"); Constructor declaredConstructorBook = classBook.getDeclaredConstructor(String.class, String.class); declaredConstructorBook.setAccessible(true); Object objectBook = declaredConstructorBook.newInstance("Android开发艺术探索", "任玉刚"); Book book = (Book) objectBook; Log.d(TAG, "reflectPrivateConstructor book = " + book.toString()); } catch (Exception ex) { ex.printStackTrace(); } } // 反射私有属性 public static void reflectPrivateField() { try { Class classBook = Class.forName("com.android.peter.reflectdemo.Book"); Object objectBook = classBook.newInstance(); Field fieldTag = classBook.getDeclaredField("TAG"); fieldTag.setAccessible(true); String tag = (String) fieldTag.get(objectBook); Log.d(TAG, "reflectPrivateField tag = " + tag); } catch (Exception ex) { ex.printStackTrace(); } } // 反射私有方法 public static void reflectPrivateMethod() { try { Class classBook = Class.forName("com.android.peter.reflectdemo.Book"); Method methodBook = classBook.getDeclaredMethod("declaredMethod", int.class); methodBook.setAccessible(true); Object objectBook = classBook.newInstance(); String string = (String) methodBook.invoke(objectBook, 0); Log.d(TAG, "reflectPrivateMethod string = " + string); } catch (Exception ex) { ex.printStackTrace(); } } // 获得系统Zenmode值 public static int getZenMode() { int zenMode = -1; try { Class cServiceManager = Class.forName("android.os.ServiceManager"); Method mGetService = cServiceManager.getMethod("getService", String.class); Object oNotificationManagerService = mGetService.invoke(null, Context.NOTIFICATION_SERVICE); Class cINotificationManagerStub = Class.forName("android.app.INotificationManager$Stub"); Method mAsInterface = cINotificationManagerStub.getMethod("asInterface", Binder.class); Object oINotificationManager = mAsInterface.invoke(null, oNotificationManagerService); Method mGetZenMode = cINotificationManagerStub.getMethod("getZenMode"); zenMode = (Integer) mGetZenMode.invoke(oINotificationManager); } catch (Exception ex) { ex.printStackTrace(); } return zenMode; } // 关闭手机 public static void shutDown() { try { Class cServiceManager = Class.forName("android.os.ServiceManager"); Method mGetService = cServiceManager.getMethod("getService", String.class); Object oPowerManagerService = mGetService.invoke(null, Context.POWER_SERVICE); Class cIPowerManagerStub = Class.forName("android.os.IPowerManager$Stub"); Method mShutdown = cIPowerManagerStub.getMethod("shutdown", boolean.class, String.class, boolean.class); Method mAsInterface = cIPowerManagerStub.getMethod("asInterface", Binder.class); Object oIPowerManager = mAsInterface.invoke(null, oPowerManagerService); mShutdown.invoke(oIPowerManager, true, null, false); } catch (Exception ex) { ex.printStackTrace(); } } public static void shutdownOrReboot(final boolean shutdown, final boolean confirm) { try { Class ServiceManager = Class.forName("android.os.ServiceManager"); // 获得ServiceManager的getService方法 Method getService = ServiceManager.getMethod("getService", String.class); // 调用getService获取RemoteService Object oRemoteService = getService.invoke(null, Context.POWER_SERVICE); // 获得IPowerManager.Stub类 Class cStub = Class.forName("android.os.IPowerManager$Stub"); // 获得asInterface方法 Method asInterface = cStub.getMethod("asInterface", Binder.class); // 调用asInterface方法获取IPowerManager对象 Object oIPowerManager = asInterface.invoke(null, oRemoteService); if (shutdown) { // 获得shutdown()方法 Method shutdownMethod = oIPowerManager.getClass().getMethod("shutdown", boolean.class, String.class, boolean.class); // 调用shutdown()方法 shutdownMethod.invoke(oIPowerManager, confirm, null, false); } else { // 获得reboot()方法 Method rebootMethod = oIPowerManager.getClass().getMethod("reboot", boolean.class, String.class, boolean.class); // 调用reboot()方法 rebootMethod.invoke(oIPowerManager, confirm, null, false); } } catch (Exception e) { e.printStackTrace(); } }}// 调用相应反射逻辑方法try { ReflectClass.reflectNewInstance(); ReflectClass.reflectPrivateConstructor(); ReflectClass.reflectPrivateField(); ReflectClass.reflectPrivateMethod();} catch (Exception ex) { ex.printStackTrace();}Log.d(TAG, " zenmode = " + ReflectClass.getZenMode());
SecurityException
。如反射调用PowerManager.shutdown()
方法时,需要确保应用有相应的权限(如REBOOT
)。反射机制为Java程序提供了强大的动态操作能力。在实际开发中,反射可以用来解决无法通过接口或子类继承关系进行操作的问题。通过Class
、Field
、Method
、Constructor
等类的反射方法,可以实现对类、对象、字段、方法等的动态操作。
如需更深入了解反射机制,可以参考Java官方文档或相关开源资料。
转载地址:http://dbqwz.baihongyu.com/