java反射
一、反射的概念
JAVA反射机制就是在运行状态中,对于任意一个类,都能知道这个类所有的属性和方法,对于任意一个对象,都能调用它的任意一个方法和属性,这种动态获取的信息以及调用对象的方法的功能称为JAVA反射机制。
二、反射的使用
反射要抓住两个点,class的获取和类对象的获取
2.1、class的获取
class的三种获取方式
要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取java.lang.Class实例?
方式 | 备注 |
---|---|
Class.forName(“完整类名带包名”) | 静态方法 |
对象.getClass() | |
任何类型.class |
2.2、类对象的获取
1.通过反射实例化对象
可以使用**对象.newInstance()**来实例化对象,
class ReflectTest{
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 通过反射机制,获取Class,通过Class来实例化对象
Class c = Class.forName("com.lvlin.User");
// newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。
// 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
Object obj = c.newInstance();
System.out.println(obj);
}
}
通过此方式可以创建类对象,
2.获取某个对象中的数据
这种方式需要获取到类对象,获取到类对象后,就可以获取类中的所有变量数据。
2.3、反射Filed
方式 | 备注 |
---|---|
public String getName() | 返回属性名 |
public int getModifiers() | 获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号【一般配合Modifier类的toString(int x)方法使用】 |
public Class<?> getType() | 以Class类型,返回属性类型【一般配合Class类的getSimpleName()方法使用】 |
public void set(Object obj, Object value) | 设置属性值 |
public Object get(Object obj) | 读取属性值 |
2.4、反射类方法
方式 | 备注 |
---|---|
public T newInstance() | 创建对象 |
public String getName() | 返回完整类名带包名 |
public String getName() | 返回类名 |
public Field[] getFields() | 返回类中public修饰的属性 |
public Field[] getDeclaredFields() | 返回类中所有的属性 |
public Field getDeclaredField(String name) | 根据属性名name获取指定的属性 |
public native int getModifiers() | 获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号【一般配合Modifier类的toString(int x)方法使用】 |
public Method[] getDeclaredMethods() | 返回类中所有的实例方法 |
public Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 根据方法名name和方法形参获取指定方法 |
public Constructor<?>[] getDeclaredConstructors() | 返回类中所有的构造方法 |
public Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 根据方法形参获取指定的构造方法 |
---- | ---- |
public native Class<? super T> getSuperclass() | 返回调用类的父类 |
public Class<?>[] getInterfaces() | 返回调用类实现的接口集合 |
反射一个类的属性
//通过反射机制,反编译一个类的属性Field(了解一下)
class ReflectTest{
public static void main(String[] args) throws ClassNotFoundException {
StringBuilder s = new StringBuilder();
Class studentClass = Class.forName("com.lvlin.testStudent");
s.append(Modifier.toString(studentClass.getModifiers()) + " class " + studentClass.getSimpleName() + " {\n");// Class类的getName方法
//获取所有的属性
Field[] fields = studentClass.getDeclaredFields();
for (Field f : fields){
s.append("\t");
// 获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
// 用Modifier类的toString转换成字符串
s.append(Modifier.toString(f.getModifiers()));
if (f.getModifiers() != 0) s.append(" ");
s.append(f.getType().getSimpleName());// 获取属性的类型
s.append(" ");
s.append(f.getName());// 获取属性的名字
s.append(";\n");
}
s.append("}");
System.out.println(s);
}
}
想要通过反射访问私有属性需要调用
public void setAccessible(boolean flag) | 默认false,设置为true为打破封装 |
---|
2.5、反射使用实例
class IntentUtil {
companion object{
const val TAG = "IntentUtil"
@JvmStatic
fun getIntentByReflect() : Intent?{
try {
val instance = ActivityManager.instance()
val activityManagerClazz = Class.forName("com.test.ActivityManager")
val activityListField = activityManagerClazz.getDeclaredField("mActivityList")
activityListField.isAccessible = true
val activityList = activityListField[instance] as List<Activity>
var pluginTransferActivity: PluginTransferActivity? = null
for (activity in activityList) {
if (activity.javaClass.name == PluginTransferActivity::class.java.name) {
pluginTransferActivity = activity as PluginTransferActivity
break
}
}
val pluginTransActivityClazz = Class.forName("com.test.PluginActivity")
val field = pluginTransActivityClazz.getDeclaredField("pluginHelper")
field.isAccessible = true
if(pluginTransferActivity != null){
val pluginHelper = field[pluginTransferActivity] as PluginHelper
val pluginActivityBean = pluginHelper.getPluginBean()
return pluginActivityBean.intent
}
return null
} catch (e: ClassNotFoundException) {
e.printStackTrace()
} catch (e: NoSuchFieldException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
}
return null
}
}
}