JAVA第十六章总结

反射与注解

反射

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

 

访问构造方法 

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

 Constructor 类的常用方法

方法说明
isVarArgs()查看该构造方法是否允许带有可变数量的参数,如果允许则返回 true,否则返回 false
getParameterTypes()按照声明顺序以Class数组的形式获得该构造方法的各个参数的类型
getExceptionTypes()以Class 数组的形式获得该构造方法可能抛出的异常类型
newInstance(Object...initargs)通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法
setAccessible(boolean flag)如果该构造方法的权限为 private,默认为不允许通过反射利用 newInstance(Objectinitargs)方法创建对象。那么,先执行该方法,并将入口参数设为 true,则允许创建
getModifiers()获得可以解析出该构造方法所采用修饰符的整数

Modifier类中的常用解析方法 

静态方法说明
isPublic(int mod)查看是否被 public 修饰符修饰,如果是则返回true,否则返回 fals
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)以字符串的形式返回所有修饰符
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 类型

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 信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值