Chapter 16 of Java: Reflection and Annotations

reflection

        Through the Java reflection mechanism, you can access the description of the Java object that has been loaded into the JVM in the program, and realize the function of accessing, detecting and modifying the information describing the Java object itself. The Java reflection mechanism is very powerful, and support for this function is provided in the java.lang.reflect package.

Access constructor 

        When a constructor is accessed through the following set of methods, an object or array of type Constructor is returned. Each Constructor object represents a constructor method.

 

The code example is as follows: 

package com.mr;
public class Demo1 {
	String s;
	int i,i2,i3;
	public Demo1(){
		
	}
	public Demo1(String s,int i) {
		this.s=s;
		this.i=i;
	}
	public Demo1(String...strings) {
		if(0<strings.length)
			i=Integer.valueOf(strings[0]);
		if(1<strings.length)
			i2=Integer.valueOf(strings[1]);
		if(2<strings.length)
			i3=Integer.valueOf(strings[2]);
	}
	public void print() {
		System.out.println("s="+s);
		System.out.println("i="+i);
		System.out.println("i2="+i2);
		System.out.println("i3="+i3);
	}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;

import com.mr.Demo1;
public class Demo {
	public static void main(String[] args) {
		Demo1 d1=new Demo1("10","20","30");
		Class<?extends Demo1>Demo1Class=d1.getClass();
		Constructor[] declaredConstructors=Demo1Class.getDeclaredConstructors();
			for(int i=0;i<declaredConstructors.length;i++) {//遍历构造方法
				Constructor<?>constructor=declaredConstructors[i];
				System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs());
				System.out.println("该构造方法的入口参数类型依次为:");
				Class[] parameterTypes=constructor.getParameterTypes();//获取所有参数类型
				for(int j=0;j<parameterTypes.length;j++) {
					System.out.println(""+parameterTypes[j]);
				}
				System.out.println("该构造方法可能抛出的异常类型为:");
				//获取所有可能抛出的异常信息类型
				Class[] exceptionTypes=constructor.getExceptionTypes();
				for(int j=0;j<exceptionTypes.length;j++) {
					System.out.println(""+exceptionTypes[j]);
				}
				Demo1 d2=null;
			while(d2==null) {
				try {//如果构造方法的访问权限为private或protected,则出现异常,即不允许访问
					if(i==2) 
						d2=(Demo1)constructor.newInstance();
						else if(i==1)
							//通过执行具有两个参数的构造方法创建对象
							d2=(Demo1)constructor.newInstance("7",5);
						else {
							Object[]parameters=new Object[] {new String[] {"100","200","300"}};
							d2=(Demo1)constructor.newInstance(parameters);	
						}
						}catch(Exception e) {
							System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
							constructor.setAccessible(true);//设置允许访问
						}
					}
				if(d2!=null) {
					d2.print();
					System.out.println();
				}
			}
			}
}

operation result:

Access member variables

        When accessing member variables through the following set of methods, an object or array of Field type will be returned.

The code example is as follows:

package com.mr;
public class Demo1 {
	int i;
	public float f;
	protected boolean b;
	private String s;
}
import java.lang.reflect.Field;
import com.mr.Demo1;

public class Demo {
	public static void main(String[] args) {
		Demo1 example=new Demo1();
		Class exampleC=example.getClass();
		Field[]declaredFields=exampleC.getDeclaredFields();//获取所有成员变量
		for(int i=0;i<declaredFields.length;i++) {//遍历成员变量
			Field field=declaredFields[i];
			System.out.println("名称为:"+field.getName());
			Class fieldType=field.getType();
			System.out.println("类型为:"+fieldType);
			boolean isTurn=true;
			while(isTurn) {
		//如果该成员变量的访问权限为private或protect,则抛出异常,即不允许访问
				try {
					isTurn=false;
					//获取成员变量值
					System.out.println("修改前的值为:"+field.get(example));
					if(fieldType.equals(int.class)) {//判断成员变量的类型是否为int型
						System.out.println("利用方法setInt()修改成员变量的值");
						field.setInt(example,168);//为int型成员变量赋值
					}else if(fieldType.equals(float.class)) {//判断成员变量的类型是否为float型
						System.out.println("利用方法setFloat()修改成员变量的值");
						field.setFloat(example,99.9F);//为float型成员变量赋值
					}else if(fieldType.equals(boolean.class)){//判断成员变量的类型是否为boolean型
						System.out.println("利用方法setBoolean()修改成员变量的值");
						field.setBoolean(example,true);//为boolean型成员变量赋值	
					}else{
						System.out.println("利用方法set()修改成员变量的值");
						field.set(example,"MWQ");//为不同类型的成员变量赋值	
				}
					//获取成员变量值
					System.out.println("修改后的值:"+field.get(example));
			}catch(Exception e) {
				System.out.println("在设置成员变量值时抛出异常,"+"下面执行setAccessible()方法");
				field.setAccessible(true);//设置为允许访问
				isTurn=true;
			}
		}
			System.out.println();
	}
	}
}

operation result:

Access member methods

        When a member method is accessed through the following set of methods, an object or array of type Method will be returned.

Annotation annotation function 

        Java provides the Annotation annotation function, which can be used in the declaration of classes, constructors, member variables, member methods, parameters, etc. This function does not affect the running of the program, but it will affect auxiliary tools such as compiler warnings.

Define Annotation type

        When defining the Annotation type, you also need to use the interface keyword used to define the interface, but you need to add an "@" before the interface word, that is, the keyword defining the Annotation type is @interface. The implicit meaning of this keyword It inherits the java.lang.annotation.Annotation interface.

 

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//用于字段、方法和参数
@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;
	
	@MyAnnotation()
	//采用默认值注释构造方法
	public Record(){
	}
	
	@MyAnnotation("立即初始化构造方法")
	//注释构造方法
	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 geInt() {
		return id;
	}
		
	@Field_Method_Parameter_Annotation(describe="设置编号")
	//成员type采用默认值注释方法
	public void seInt(
		//注释方法的参数
		@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;
	}
}

Access Annotation Information

         If @RetentionPolicy.RUNTIME is specified when defining the Annotation type, the relevant Annotation information can be obtained through reflection when running the program, such as obtaining the Annotation information of the constructor, fields and methods.

Guess you like

Origin blog.csdn.net/nmy15570188135/article/details/134006217