反射初理解

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(); ```