我这些学习笔记,记录的都是我自己认为的知识点,可能以后再看的时候还要翻书,但是可以用来定位到准确的书中示例的位置,减少翻书重找的时间,利于自身知识体系的搭建。 self-transcendence
第16章 反射
16.1 Class类与Java反射
通过java反射机制,可以在程序中访问已经装载到JVM中的java对象的描述,实现访问、检测和修改描述java对面本身信息的功能。
(知识点:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。通俗的讲就是反射可以在运行时根据指定的类名获得类的信息。)
所有java类都继承Object类,在Object类中定义了一个getClass()方法,该方法返回一个类型为Class的对象。利用返回的class对象,可以用来返回该对象的描述信息,方法如下:
组成部分 | 访问方法 | 返回值类型 | 说明 |
包路径 | getPackage() | Package对象 | 获得该类的存储路径 |
类名称 | getName() | String对象 | 获得该类的名称 |
继承类 | getSuperclass() | Class对象 | 获得该类继承的类 |
实现接口 | getInterfaces() | Class型数组 | 获得该类实现的所有借口 |
构造方法 | getConstructors() | Constructor型数组 | 获得所有权限为public的构造方法 |
getConstructor(Class<?>...parameterTypes) | Constructor对象 | 获得权限为public的指定构造方法 | |
getDeclaredConstructors() | Constructor型数组 | 获得所有构造方法,按声明顺序返回 | |
getDeclaredConstructor(Class<?>...parameterTypes) | Constructor对象 | 获得指定方法 | |
方法 | getMethods() | Method型数组 | 获得所有权限为public的方法 |
getMethod(Stringname,C lass<?>...parameterTypes) | Method对象 | 获得权限为public的指定方法 | |
getDeclaredMethod() | Method型数组 | 获得所有方法按声明顺序返回 | |
getDeclaredMethod(String name,Class<?>...paramete rTypes) | Method对象 | 获得指定方法 | |
成员变量 | getFields() | Field型数组 | 获得所有权限为public的成员变量 |
getField(String name) | Field对象 | 获得权限为public的指定成员变量 | |
getDeclaredFields() | Field型数组 | 获得所有成员变量按声明顺序返回 | |
getDeclaredField(String name) | Field对象 | 获得指定成员变量 | |
内部类 | getClass() | Class型数组 | 获得所有权限为public的内部类 |
getDeclaredClasses() | Class型数组 | 获得所有内部类 | |
内部类的声明类 | getDeclaringClass() | Class对象 | 如果该类为内部类,则返回他的成员类,否则返回null |
16.1.1 访问构造方法
通过下列一组方法访问构造方法时,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法。
A. getConstructors()
B. getConstructor(Class<?>...parameterTypes)
C. getDeclaredConstructors()
D. getDeclaredConstructor(Class<?>...parameterTypes)
如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。例如,访问一个入口参数类型依次为String和int型的构造方法,通过下面两种方法实现:
objectClass.getDeclaredConstructors(String.class,int.class);
objectClass.getDeclaredConstructors(new Class[]{String.class,int.class});
Constructor类中提供的常用方法如下:
方法 | 说明 |
isVarArgs() | 查看该构造方法是否允许带有可变数量的参数,有是true没是false |
getParameterTypes() | 按照声明顺序以Class数组的形式获得构造方法可能抛出的异常类型 |
getExceptionTypes() | 以Class数组的形式获得该构造方法可能抛出的异常类型 |
newInstance(Object...initargs) | 通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法 |
setAccessible(boolean flag) | 如果该构造方法的权限为private,默认为不允许通过反射利用newIns tance(Object...initargs)方法创建对象。如果该先执行该方法,并将入口参数设置为true,则允许创建 |
getModifiers() | 获得可以解析出该构造方法所采用修饰符的整数。 |
Modifier类可以解析出getModifiers()方法的返回值所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以以字符串的形式获得所有的修饰符。
静态方法 | 说明 |
isPublic(int mod) | 查看是否被public修饰符修饰,如果是则返回true,否则返回false |
isProtected(int mod) | 查看是否被protected修饰符修饰,如果是则返回true,否则返回false |
isPrivate(int mod) | 查看是否被private修饰符修饰,如果是则返回true,否则返回false |
isStatic(int mod) | 查看是否被static修饰符修饰,如果是则返回true,否则返回false |
isFinal(int mod) | 查看是否被final修饰符修饰,如果是则返回true,否则返回false |
toString(int mod) | 以字符串的形式返回所有修饰符 |
判断对象constructor所代表的构造方法是否被private修饰,以及以字符串形式获得该构造方法的所有修饰符的典型代码如下:
Int modifiers=constructor.getModifiers();
Boolean isEmbellishByPrivate=Modifier.isPrivate(modifiers);
String embllishment=modifier.toString(modifiers);
16.1.2 访问成员变量
通过下面的方法访问成员变量的时,将返回Field类型的对象或数组。每个field对象代表一个成员变量,利用field对象可以操纵相应的成员变量:
A. getFields()
B. getField(String name)
C. getDeclaredFields()
D. getDeclaredFields(String name)
Name是指定的成员变量的名字
方法 | 说明 |
getName() | 获得该成员变量的名称 |
getType() | 获得表示该成员变量类型的Class对象 |
get(Object obj) | 获得指定对象obj中成员变量的值,返回值为Object型 |
set(Object obj, Object value) | 将指定对象obj中成员变量的值设置为value |
getInt(Object o) | 获得指定对象obj中类型为int的成员变量的值 |
setInt(Object o,int i) | 将指定对象obj中类型为int的成员变量的值设置为i |
getFloat(Object o) | 获得指定对象obj中类型为float的成员变量的值 |
setFloat(Object o, Float f) | 将指定对象obj中类型为float的成员变量的值设置为f |
getBoolean(Object o) | 将获得指定对象obj中类型为boolean的成员变量的值 |
setBoolean(Object o,boolean z) | 将指定对象obj中类型为boolean的成员变量的值设置为z |
setAccessible(boolean flag) | 此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量 |
getModifiers() | 获得可以解析出该成员变量所采用的的修饰符的整数 |
16.1.3 访问方法
下面的方法使用时,将返回Method类型的对象或数组。每个Method对象代表一个方法,利用Method对象可以操纵相应的方法。
A. getMethods()
B. getMethod(String name,Class<?>...parameterTypes)
C. getDeclaredMethods()
D. getDeclaredMethod(String name,Class<?>...parameterTypes)
如果访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。例如:访问一个名称为print入口参数类型依次为String和int的方法:
A. objectClass.getDeclaredMethod(“print”,String.class,int.class);
B. objectClass.getDeclaredMethod(“print”,new Class[]{String.class,int.class});
Method常用方法:
方法 | 说明 |
getName() | 获得该方法的名称 |
getParameterTypes() | 按照声明顺序以Class数组的形式获得该方法的各个参数的类型 |
getReturnType() | 以Class对象的形式获得该方法的返回值的类型 |
getExceptionTypes() | 以Class数组的形式获得该方法可能抛出的异常类型 |
invoke(Object obj, Object...args) | 利用指定参数args执行指定对象obj中的该方法,返回值为object型 |
isVarargs() | 查看该构造方法是否运行带有可变数量的参数,如果允许则返回true,否则false |
getModifiers() | 获得可以解析出该方法所采用修饰符的整数 |
---------------------------------------------------------------------
16.2 使用Annotation功能
该功能可用于类、构造方法、成员变量、方法、参数等的声明中。该功能并不影响程序的运行,但是会对编译器警告等辅助工具产生影响。
16.2.1 定义Annotation类型
定义Annotation类型时,也需要用到用来定义接口的interface关键字,但需要在interface关键字前加一个@符号,即定义Annotation类型的关键字为@interface,这个关键字的隐含意思是继承了java.lang.annotation.Annotation接口。例如,下面的代码就定义了一个Annotation类型:
Public @interface NoMemberAnnotation{}
这个定义的Annotation类型@NoMemberAnnotation没有包含任何成员,这样的Annotation类型被称为marker annotation。下面的代码定义了一个只包含一个成员的Annotation类型:
Public @interface OneMemberAnnotation{
String value();
}
完全没搞懂这个Annotation是干什么用的,等用到或者全书看完之后,再回头浏览