0%

4_反射

[TOC]

反射的主要功能: 在运行状态下,根据 类的部分已知信息 来获取 类的完全信息。

Class类

在介绍 反射时,先了解一下 Class 类。

Class类和普通类的关系

普通类: 表示常见的Integer、Long和自定义的类。普通类是对某一事物的抽象。
Class类: 是对普通类的抽象。普通类的公共属性有 构造方法、普通方法、父类、接口等等,将这些公共属性进行抽象后,就是一个Class类。

获取Class类的对象

通过全类名获取普通类的Class对象

Class mClass = Class.forName(“custom.MyClass”);

通过得 .class 属性获取

Class mClass = MyClass.class;

通过类对象的getClass方法

Class mClass = myClass.getClass();

获取普通类的对象

通过Class对象。由于newInstance()方法调用的是类的无参构造函数,因此该方式要求MyClass类必须拥有无参构造函数。

MyClass m = (MyClass)class.newInstance();

使用 new 关键字

MyClass m = new MyClass();

Class类的常用方法

构造方法

从注释可以看出,Class的构造函数是私有的,他只能被JVM调用。

1
2
3
4
5
6
7
8
9
10
/*
* Private constructor. Only the Java Virtual Machine creates Class objects.
* This constructor is not used and prevents the default constructor being
* generated.
*/
private Class(ClassLoader loader) {
// Initialize final field for classLoader. The initialization value of non-null
// prevents future JIT optimizations from assuming this final field is null.
classLoader = loader;
}

获取public方法

获得所有public构造方法

Constructor [] constructors = Class.forName(“java.lang.String”).getConstructors();

获得某一个构造方法,getConstructor()方法参数为可变参数

Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

获取普通类的public方法函数

Method[] methods = clazz.getMethods();

获取普通类的public字段信息

Field[] fields = clazz.getFields();

创建普通类的实例

String str=(String) constructor.newInstance(new StringBuffer(“abc”));

获取非public方法

以上介绍的都是获取public属性的方法或者字段。若要获取非public的字段,需要使用带Declared的方法。如getDeclaredMethod()

1
2
3
4
5
6
Method[] methods = clazz.getDeclaredMethods();
System.out.println("MethodDeclaration in " + clazz.getName());
for(Method method : methods){
method.setAccessible(true);
System.out.println(method.getName());
}

获取类的泛型类型

1
2
3
4
5
6
7
8
9
10
11
Class<T> clazz;
Type genericSuperclass = getClass().getGenericSuperclass();
if(genericSuperclass instanceof ParameterizedType){
//参数化类型
ParameterizedType parameterizedType= (ParameterizedType) genericSuperclass;
//返回表示此类型实际类型参数的 Type 对象的数组
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
//因为泛型参数会有多个,
clazz= (Class<T>)actualTypeArguments[0];
}else{
clazz= (Class<T>)genericSuperclass;

反射

反射的主要功能: 在运行状态下,根据 类的部分已知信息 来获取 类的完全信息。

部分已知信息: 全类名 或者 类的对象 等
类的全部信息: 类的属性、方法、继承关系和注解等内容。即 对应的 Class类 对象。

作用

  1. 获取程序在运行时刻的内部结构。
  2. 在运行时刻对一个java对象进行操作。
  3. 绕过java的访问控制,使用对象的私有方法。