Java 反射学习

 
Class类与Java反射
通过Java反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问、检测和修改描述Java对象本身信息的功能。
Object类中定义了一个getClass()方法,该方法返回一个类型为Class的对象

在通过getFields()和getMethods()方法以此获得权限为public的成员变量和方法时,将包含从超类中继承到的成员变量和方法;而通过方法getDeclaredFields()和getDeclaredMethods()只是获得在本类中定义的所有成员变量和方法。
 
访问构造方法
getConstructors()
getConstructors(Class<?>···parameterTypes)
getDeclaredConstructors()
getDeclaredConstructors(Class<?>···parameterTypes)
如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。例如,访问一个入口参数类型依次为String和int型的构造方法,通过下面两种方法均可实现。
objectClass.getDeclaredConstructor(String.class, int.class);
objcetClass.getDeclaredConstructor(new Class[] {String.class, int.class}); 
 
方法 说明
isVarArgs() 查看该构造方法是否允许带有可变数量的参数,如果允许则返回true,否则返回false
getParameterTypes() 按照声明顺序以Class数组的形式获得该构造方法的各个参数的类型
getExceptionTypes() 以Class数组的形式获得该构造方法可能抛出的异常类型
newInstance(Object···initargs) 通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法
setAccessible(boolean flag) 如果该构造方法的权限为private,默认为不允许通过反射利用newInstance(Object···initargs)方法创建对象。如果先执行该方法,并将入口参数设为true,则允许创建
getModifiers() 获得可以解析出该构造方法所采用修饰符的整数
 
java.lang.reflect.Modifier类可以解析出getModifier()方法的返回值所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,即可以查看是否被指定的修饰符修饰,还可以以字符串的形式获得所有修饰符。 
 
静态方法 说明
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) 以字符串的形式返回所有的修饰符 

例:
Int modifiers = constructor.getModifiers();
Boolean isEmbellishByPrivate = Modifier.isPrivate(modifiers);
String embelishment = Modifier,toString(modifiers); 
 
访问成员变量

 

访问方法
objectClass.getDeclaredMethod(“print”,String.class, int.class);
objectClass.getDeclaredMethod(“print”, new Class[] {String.class, int.class});

 
定义Annotation类型
在定义Annotation类型时,也需要用到用来定义接口的interface关键字, 但需要在interface关键词前加一个“@”符号,即定义Annotation类型的关键字为@interface,这个关键字的隐含意思是继承了java.lang.annotation.Annotation接口。
 
例: public @interface NoMemberAnnotation{
}
这样未包含任何成员的Annotation类型@NoMemberAnnotation被称为marker.annotation。
 
Public @interface OneMemberAnnotation{
String value();
}
Annotation可用的成员类型有String、Class、primitive、enumerated和annotation,以及所列类型的数组。
Value:成员变量名称,如果在所定义的Annotation类型中只包含一个成员,通常将成员名称命名为value。
 
在为Annotation类型定义成员时,也可以为成员设置默认值。例如,下面的代码在定义Annotation类型时就为成员设置了默认值。
Public @interface DefaultValueAnnotation{
    String describe() default “<默认值>”;
    Class type() default void.class;
}
在定义Annotation类型时,还可以通过Annotation类型@Target来设置Annotation类型适用的程序元素种类。如果未设置@Target,则表示适用于所有程序元素。枚举类ElementType中的枚举常量用来设置@Target
 
访问Annotation信息
如果在定义Annotation类型时将@Retention设置为RetentionPolicy.RUNTIME,那么在运行程序时,通过反射就可以获取到相关的Annotation信息,如获取构造方法、字段和方法的Annotation信息。
类Constructor、Field和Method均继承了AccessibleObject类,在AccessibleObject中定义了3个关于Annotation的方法,其中方法isAnnotationPresent(Class<? extends Annotation> annotationClass)用来查看是否添加了指定类型的Annotation,如果是则返回true,否则返回false;方法getAnnotation(Class<T> annotationClass)用来获得指定类型的Annotation,如果存在则返回true,否则返回false;方法getAnnotation(Class<T> annotationClass)用来获得指定类型的Annotation,如果存在则返回相应的对象,否则返回null;方法getAnnotations()用来获得所有的Annotation,该方法将返回一个Annotation数组.
在类Constructor和Method中还定义了方法getParameterAnnotations(),用来获得为所有参数添加的Annotation,将以Annotation类型的二维数组返回,在数组中的顺序与声明的顺序相同,如果没有参数则返回一个长度为0的数组;如果存在未添加Annotaion的参数,将用一个长度为0的嵌套数组占位。 
posted @ 2018-10-29 19:20  Zzzwww  阅读(301)  评论(0编辑  收藏  举报
/* 看板娘 */