第十六章 反射

反射

利用Java反射机制,可以在程序运行时访问类的所有描述信息(经常需要访问的有 类的构造方法、成员变量和方法),实现逆向控制程序的执行过程

Class类与Java反射

  1. 通过在Object类中定义的getClass()方法返回一个类型为Class的对象,再用该对象的一些方法,即可访问描述 textField对象的主要描述信息
    如:
Class textFieldC = textField.getClass();

在这里插入图片描述

  • 在通过getFields()和getMethods()方法依次获得权限为public的成员变量和方法时,将包含从超类中继承到的成员变量和方法;而通过方法getDeclareFields()和getDeclaredMethods()只是获得在本类中定义的所有成员变量和方法。

访问构造方法Constructor

  1. 如果访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问,如:
objectClass.getDeclaredConstructor(String.class,int.class)
  1. 通过java.lang.reflect.Modifier类可以解析出getModifiers()方法的返回值所表示的修饰符信息,public、protected、private、static、final等

具体方法查看API

访问成员变量Field

每个Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量。

访问方法Method

如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。如,访问一个名称为print、入口参数类型一次为String和int型的方法:

objectClass.getDeclaredMethod("print",String.class,int.class);
	上述三个类具体方法查API

使用Annotation功能

该功能可用于类、构造方法、成员变量、方法、参数等的声明中。该功能并不影响程序的运行,但是会对编译器警告等辅助工具产生影响。

Annotation即注释,看了下代码,是一种和之前一些代码相比比较不同的东西。

定义Annotation类型

定义Annotation类型的关键字为@interface,这个关键字的隐含意思是继承java.lang.annotation.Annotation接口。如:

public @interface NoMemberAnnotation{
}
public @interface OneMemberAnnotation{
	String value()
}
  • String:成员类型。可用的成员类型有StringClassprimitiveenumerateannotation以及所列类型的数组
    包含多个成员的Annotation类型:
public @interface MoreMemberAnnotation{
	String describe();
	Class Type();
}

在为Annotation类型定义成员时,也可以为成员设置默认值。如:

public @interface DefaultValueAnnotation{
	String describe() default"<默认值>";
	Class type() default void.class;
}

可以通过Annotation类型@Target来设置Annotation类型适用的程序元素种类。枚举类ElementType中的枚举常量用来设置@Target。

枚举常量说明
ANNOTATION_TYPEAnnotation类型
CONSTRUCTOR构造方法
FIELD成员变量和枚举常量
LOCAL_VARIABLE局部变量
METHOD方法
PACKAGE包装
PARAMETER正式参数
TYPE类,接口(包括注释类型)或枚举
TYPE_PARAMETER键入参数
TYPE_USE使用类型

通过Annotation类型@Retention可以设置Annotation的有效范围。枚举类RetentionPolicy中的常量用来设置@Retention,如未设置@Retention,Annotation的有效范围为枚举常量CLASS表示的范围。

枚举常量说明
SOURCE不变异Annotation到类文件中,有效范围最小
CLASS编译Annotation到类文件中,但是运行时不加载Annotation到JVM中
RUNTIME运行时加载Annotation到JVM中,有效范围最大

例:

import java.lang.annotation.*;

@Target(ElementType.CONSTRUCTOR)
// 用于构造方法
@Retention(RetentionPolicy.RUNTIME)
// 在运行时加载Annotation到JVM中
public @interface Constructor_Annotation {
	String value() default "默认构造方法"; // 定义一个具有默认值的String型成员
}
import java.lang.annotation.*;

// 用于字段、方法和参数
@Target( { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
// 在运行时加载Annotation到JVM中
public @interface Field_Method_Parameter_Annotation {
	String describe(); // 定义一个没有默认值的String型成员
	
	Class type() default void.class; // 定义一个具有默认值的Class型成员
}
public class Record {
	@Field_Method_Parameter_Annotation(describe = "编号", type = int.class)
	// 注释字段
	int id;
	@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
	String name;
	
	@Constructor_Annotation()
	// 采用默认值注释构造方法
	public Record() {
	}
	
	@Constructor_Annotation("立即初始化构造方法")
	// 注释构造方法
	public Record(
		@Field_Method_Parameter_Annotation(describe = "编号",
				type = int.class) int id,
		@Field_Method_Parameter_Annotation(describe = "姓名",
				type = String.class) String name) {
		this.id = id;
		this.name = name;
	}
	
	@Field_Method_Parameter_Annotation(describe = "获得编号", type = int.class)
	// 注释方法
	public int getId() {
		return id;
	}
	
	@Field_Method_Parameter_Annotation(describe = "设置编号")
	// 成员type采用默认值注释方法
	public void setId(
	// 注释方法的参数
			@Field_Method_Parameter_Annotation(describe = "编号",
					type = int.class) int id) {
		this.id = id;
	}
	
	@Field_Method_Parameter_Annotation(describe = "获得姓名",
			type = String.class)
	public String getName() {
		return name;
	}
	
	@Field_Method_Parameter_Annotation(describe = "设置姓名")
	public void setName(
			@Field_Method_Parameter_Annotation(describe = "姓名",
					type = String.class) String name) {
		this.name = name;
	}
}

访问Annotation信息

  1. 将@Retention设置为RetentionPolicy.RUNTIME,运行程序时通过反射就可以获取到相关的Annotation信息。
  2. 类Constructor、Field和Method均继承了AccessibleObject类。在AccessibleObject定义了三个关于Annotation的方法。
方法说明
isAnnotationPresent(Class<? extends Annotation> annotationClass)查看是否添加了指定类型的Annotation
getAnnotation(Class annotationClass)获得指定类型的Annotation
getAnnotations()获得所有的Annotation

在类Constructor和Method中还定义了方法getParameterAnnotations(),用来获得为所有参数添加的Annotation。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值