反射

https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650825931&idx=1&sn=b61ed2ad2665cbc3a89351b161223769&chksm=80b7b055b7c03943f10f1e8b3697d3d33bbfc98d38e40c9ecbc6a3ab34f700a065858f8c8ce9&scene=38#wechat_redirect

在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。[1]用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。

Java 反射主要提供以下功能:

在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
在运行时调用任意一个对象的方法

// 即以下方法都属于Class 类的方法。

<-- 1. 获取类的构造函数(传入构造函数的参数类型)->>
// a. 获取指定的构造函数 (公共 / 继承)
Constructor getConstructor(Class... parameterTypes)
// b. 获取所有的构造函数(公共 / 继承)
Constructor[] getConstructors();
// c. 获取指定的构造函数 ( 不包括继承)
Constructor getDeclaredConstructor(Class... parameterTypes)
// d. 获取所有的构造函数( 不包括继承)
Constructor[] getDeclaredConstructors();
// 最终都是获得一个Constructor类对象

// 特别注意:
// 1. 不带 "Declared"的方法支持取出包括继承、公有(Public) & 不包括有(Private)的构造函数
// 2. 带 "Declared"的方法是支持取出包括公共(Public)、保护(Protected)、默认(包)访问和私有(Private)的构造方法,但不包括继承的构造函数
// 下面同理

<-- 2. 获取类的属性(传入属性名) -->
// a. 获取指定的属性(公共 / 继承)
Field getField(String name) ;
// b. 获取所有的属性(公共 / 继承)
Field[] getFields() ;
// c. 获取指定的所有属性 (不包括继承)
Field getDeclaredField(String name) ;
// d. 获取所有的所有属性 (不包括继承)
Field[] getDeclaredFields() ;
// 最终都是获得一个Field类对象

<-- 3. 获取类的方法(传入方法名 & 参数类型)-->
// a. 获取指定的方法(公共 / 继承)
Method getMethod(String name, Class... parameterTypes) ;
// b. 获取所有的方法(公共 / 继承)
Method[] getMethods() ;
// c. 获取指定的方法 ( 不包括继承)
Method getDeclaredMethod(String name, Class... parameterTypes) ;
// d. 获取所有的方法( 不包括继承)
Method[] getDeclaredMethods() ;
// 最终都是获得一个Method类对象

<-- 4. Class类的其他常用方法 -->
getSuperclass();
// 返回父类

String getName();
// 作用:返回完整的类名(含包名,如java.lang.String )

Object newInstance();
// 作用:快速地创建一个类的实例
// 具体过程:调用默认构造器(若该类无默认构造器,则抛出异常
// 注:若需要为构造器提供参数需使用java.lang.reflect.Constructor中的newInstance()
通过 Class 对象分别获取Constructor类对象、Method类对象 & Field 类对象
Class serviceManager = null;
try {
serviceManager = Class.forName("android.os.ServiceManager");
System.out.println(serviceManager);
//获取方法
Method getService = serviceManager.getMethod("getService", String.class);
//调用方法
IBinder iBinder = (IBinder) getService.invoke(serviceManager.newInstance(), "InputService");
System.out.println(iBinder);
} catch (Exception e) {
e.printStackTrace();
}

getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。

getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。

小技巧 :getDeclaredMethods的效率高,但是只能查询自身的类方法,如果没找到可以再次尝试getMethods()获得

如下参考EventBus中 SubscriberMethodFinder.java部分片段:
try {
// This is faster than getMethods, especially when subscribers are fat classes like Activities
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}

你可能感兴趣的:(反射)