反射初理解
2021-05-29 17:47:55
#### 反射
能够分析类能力的程序称为**反射(reflective)**.
反射机制可以用来:
- 在运行时分析类的能力
- 在运行时检查对象
- 实现泛型数组操作代码
- 利用Method方法
##### Class类
getClass()方法会返回Class类的一个实例
虚拟机为每一个类型管理一个**唯一** 的Class对象.因此可以使用==实现两个类对象的比较:
`if (e.getClass() == Employee.class)`
这个比比较和 `e instanceof Employee` 不同,因为instanceof是子类也是true,但是这个必须是相同的类.
##### 利用反射分析类的能力
java.lang.reflect包中有三个类Field, Method, Constructor分别用于描述类的属性,方法,构造器. 方法见**类方法摘要**
##### 使用反射在运行时分析对象
上面的方法可以轻松获得一个类的属性名和类型,下面是如何获取一个具体对象里的属性的值.
代码如下:使用f的get(Student s)方法和set(Student s, Object o),将对象放在括号里面.
``` java
Student harry = new Student(18,"harry");//年龄,姓名
Class cl = harry.getClass();
Field f = cl.getDeclaredField("name");
Object o = f.get(harry);
f.set(harry, "xiaoming");
```
但是属性一般都是私有的,所以一般使用get和set都会报错,所以需要先将其访问控制修改掉.
```java
//将访问权限设置为可访问,其中有可能会被拒绝然后抛出一个异常
f.setAccessible(true);
```
AccessibleObject类是Field, Method, Constructor的公共超类.
##### 调用任意方法和构造器
Method方法有一个inoke方法
```java
//方法签名
Object invoke(Object obj, Object... args);
//如果m1代表getName()方法,通过getMethod(“getName”)获得;
//基本数据类型会自动拆装箱
String n = (String)m1.invoke(harry);
```
### 类方法摘要
##### java.lang.Class
```java
//java.lang.Class
//通过在对象上使用getClass()可以得到该类
Employee e;
Class cl = e.getClass();
//获取该类的类名
public String getName();
//静态方法,通过类名(包名+类名)来获得这个类
static Class forName(String className) throws ClassNotFoundException;
//有Declared是仅仅包含自己的,无Declared包含父类的
//获取构造器
Constructor getConstructor(Class... parameterTypes);
Constructor[] getConstructors();
Constructor[] getDeclaredConstructors();
//获取属性
//如果Class没有属性,或者是基本数据类型或者数组类型,返回空数组
Field getField(String fieldName);
Field[] getFields();
Field[] getDeclaredFields();
//获取方法
Method getMethod(String methodName);
Method[] getMethods();
Method[] getDeclaredMethods();
//获取包名
//现在貌似是getPackage().getName()
String getPackageName();
//获取注解类
<A extends Annotation>A getAnnotation(A annotation);
Annotation[] getAnnotations();
```
##### java.lang.reflect.Constructor+java.lang.reflect.Field+java.lang.reflect.Method
```java
//java.lang.reflect.Constructor
//java.lang.reflect.Field
//java.lang.reflect.Method
//通过构造器获得一个新实例
Object newInstance(Object... patams);
//返回定义这个构造器,方法,属性的类,是Class,和后面的getType不同
Class getDeclaringClass();
//返回抛出的异常类型类数组,Class(属性无)
Class[] getExceptionTypes();
//返回修饰符数字(public static final等),这个数字可以用Modifier类的静态方法toString解析
int getModifiers();
//返回名称
String getName();
//返回参数类型类数组(属性无)
Class[] getParameterTypes();
//返回返回值类(方法有)
Class getReturnType();
//获取和设置属性值
Object get(Object obj);
void set(Object obj, Object newValue);
```
##### java.lang.reflect.Modifier
```java
//java.lang.reflect.Modifier
//解析访问修饰符
static String toString(int modifiers);
//各种判断方法,例子
static boolean isFinal(int modifiers);
```
##### java.lang.reflect.AccessibleObject
```java
//java.lang.reflect.AccessibleObject
//设置访问权限
void setAccessible(boolean flag);
//查看访问权限
boolean isAccessible();
```