Java的第十六章:反射与注解

反射

        通过Java反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问、检测和修改描述Java对象本身信息的功能。Java反射机制的功能十分强大,在java.lang.reflect包中提供了对该功能的支持。

访问构造方法 

        在通过下列一组方法访问构造方法时,将返回 Constructor 类型的对象或数组。每个Constructor 对象代表一个构造方法。

 

代码案例如下: 

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();
				}
			}
			}
}

运行结果:

访问成员变量

        在通过下列一组方法去访问成员变量时,将返回 Field 类型的对象或数组。

代码案例如下:

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();
	}
	}
}

运行结果:

访问成员方法

        在通过下列一组方法访问成员方法时,将返回 Method 类型的对象或数组。

Annotation 注解功能 

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

定义 Annotation 类型

        在定义  Annotation 类型时,也需要用到用来定义接口的 interface 关键字,但需要在 interface字前加一个 “@” 符合,即定义 Annotation 类型的关键字为 @interface,这个关键字的隐含意思是继承了 java.lang.annotation.Annotation 接口。

 

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;
	}
}

访问  Annotation 信息

         如果在定义 Annotation 类型时将@RetentionPolicy.RUNTIME,那么在运行程序时通过反射就可以获取到相关的 Annotation 信息,如获取构造方法、字段和方法的  Annotation 信息。

猜你喜欢

转载自blog.csdn.net/nmy15570188135/article/details/134006217
今日推荐