16.1 反射
反射(Reflection)是指在运行时获取类的信息,并可以动态调用类的方法、访问或修改类的属性,以及构造对象的能力。 Java的反射提供了一套API,允许你在运行时检查类的结构、调用类的方法、获取和设置类的属性,甚至可以实例化对象,而不需要在编译时知道类的具体信息。
反射的一些常见用途包括:
动态加载类:可以在运行时加载未知的类。
在运行时获取类的信息:包括类的名称、父类、接口、方法、字段等。
动态创建对象:可以通过反射在运行时实例化对象,而不需要在编码时知道具体的类。
动态调用方法:可以在运行时调用类的方法,包括私有方法。
动态访问和修改属性:可以在运行时获取和修改类的属性,包括私有属性。
16.1.1 访问构造方法
在通过下列一组方法访问构造方法时,将返回 Constructor 类型的对象或数组。每个Constuetor对代表一个构造方法,利用 Constructor 对象可以操纵相应的构造方法;
例题16.1:反射一个类的所有的构造方法
16.1.2 访问成员变量
在Java中,可以使用反射机制来实现对成员变量的访问。通过反射,可以获取类的字段信息,包括字段的名称、类型等,并且可以在运行时修改它们的值,甚至可以访问私有字段。 反射提供了以下方法来访问成员变量:
getField()
getField(String name)
getDeclaredField()
getDeclaredField(String name)
使用反射访问成员变量可以在运行时动态地获取和修改类的状态,但也要小心使用,因为过度使用反射可能会导致代码变得难以维护和理解。
例题16.2:反射一个类的所有成员变量
16.1.3 访问成员方法
访问成员方法是指通过代码动态地调用一个类的方法。在Java中,可以使用反射机制来实现对成员方法的访问。通过反射,可以获取类的方法信息,包括方法的名称、参数类型等,并且可以在运行时调用它们。
反射提供了以下方法来访问成员方法:
getMethod()
getMethod(String name, Class<?>... parameterTypes)
getDeclaredMethod()
getDeclaredMethod(String name, Class<?>... parameterTypes)
例题16.3:反射一个类的所有成员方法
16.2 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();
}
String: 成员类型。可用的成员类型有 String、Class、primitive、 enumerated和annotation以及所列类型的数组。
value:成员名称。如果在所定义的 Annotation 类型中只包含一个成员,通常将成员名称命名为 value。
下面的代码定义了一个包含多个成员的 Annotation 类型:
public @interface MoreMemberAnnotation {
String describe();
Class type();
}
在为Annotation 类型定义成员时,也可以为成员设置默认值。例如,下面的代码在定义Amnotation类型时就为成员设置了默认值:
public @interface DefaultValueAnnotation {
String describe() default "<默认值>";
Class type() default void.class;
}
在定义 Annotation 类型时,还可以通过 Annotation 类型@Target 来设置 Annotation 类型适用的程序元素种类。如果未设置@Target,则表示适用于所有程序元素。枚类 ElementType 中的枚举常量用来道@Targer,如表16.6所示。
内置注解
@Override 限定重写父类方法 作用范围成员方法
@SuppressWarnings 抑制编译器警告 作用范围类、成员属性、成员方法
@Deprecated 标示已过时 作用范围类、成员属性、成员方法
例题16.4:创建自定义的注释
16.2.2 访问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,如果存在则返回相应的对象,否则返回null;方法getAnnotations()用来获得所有的Annotation,该方法将返回一个Annotation数组。
在Constructor类和Method类中还定义了方法getParameterAnnotations(),用来获得为所有参数添加的 Annotation,将以Annotation类型的二维数组返回,在数组中的顺序与声明的顺序相同。如果没有参数则返回一个长度为0的数组;如果存在未添加Annotation的参数,将用一个长度为0的嵌套数组占位。
例题16.5:访问注释中的信息
看不懂啊,怎么扩展