java反射机制学习笔记

java反射机制学习笔记

计划想系统的学习一下java反射机制、注解知识,然后自己实现一个ORM框架来加深和巩固对这部分知识的理解。本片文章对java反射机制常用的API进行了总结,并提供了一个代码事例来理解java反射API。

java反射机制总结


如果看不清图片,请鼠标右键选择在新标签也打开。

这张思维导图并没有用连接线关联出它们之间的继承关系,但是有几个重要的继承和实现关系我们需要知道。
  1. Class类实现了以下接口:
    java.io.Serializable;用于序列化
    java.lang.reflect.GenericDeclaration;读取泛型
    java.lang.reflect.Type;读取泛型
     java.lang.reflect.AnnotatedElement:用于读取注解
  2. Constructor<T>和Method类实现了以下接口:
    java.lang.reflect.GenericDeclaration;读取泛型
    java.lang.reflect.Member;获取方法名字、访问修饰符等相关信息
    继承了以下类:
    java.lang.reflect.AccessibleObject;取消默认的java语言控制访问检查能力

  3. Field类实现了以下接口:
    java.lang.reflect.Member;获取字段名字、访问修饰符等相关信息
    继承了一下类:
    java.lang.reflect.AccessibleObject;取消默认的java语言控制访问检查能力

  4. AccessibleObject类继承了以下类:
     java.lang.reflect.AnnotatedElement;用于读取注解

java反射这一部分对泛型的读取以及读取泛型的用途还没有搞清楚,希望在以后的应用中能接触到并搞懂。

java反射代码事例

CleverAnimal.java
package reflection;

public class CleverAnimal {
	
	public String color;
	
	private int height;
	private int  weight;
}
Sports.java
package reflection;

public interface Sports {
	
	String SPROTS_TYPE = "RUN";
	
	void run();
}
People.java
package reflection;

public class People extends CleverAnimal implements Sports {
	
	public String SPROTS_TYPE = "RUN";
	
	public String name;
	
	private long id;
	private int age;
	
	public People(){}
	
	public People(long id, int age){
		this.id=id;
		this.age=age;
	}
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("学生跑步");
	}
	
}
ElementDesc.java
package reflection;

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

@Target({ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.FIELD,ElementType.TYPE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ElementDesc {
	//对应用此注解元素的一个描述(或者说简介)
	public String value() default "什么都没有";
}
Student.java
package reflection;

import java.io.Serializable;

@ElementDesc(value = "Student类,为了理解反射和注解读取的事例")
public class Student extends People implements Serializable {
	
	@ElementDesc(value="schoolName字段,代表学校名称")
	public String schoolName;
	
	private String subject;
	private int grade;
	
	public Student(){}
	
	public Student(long id, int age, String subject,int grade){
		this(id, age);
		this.subject=subject;
		this.grade=grade;
	}
	
	@ElementDesc(value="我是一个私有的Student构造方法,你或许可以通过反射来调用我")
	private Student(@ElementDesc(value="唯一凭证")long id, int age){
		super(id,age);
	}
	
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public int getGrade() {
		return grade;
	}
	public void setGrade(int grade) {
		this.grade = grade;
	}
	
	@ElementDesc(value="我是一个Student类私有方法,你或许可以通过反射来调用我,我叫 privateMethod.")
	private void privateMethod(){
		System.out.println("学生的私有方法。");
	}	
}
ReflectionExample.java
package reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class ReflectionExample {

	public static void main(String [] args){
		//fieldExample();
		//methodExample();
		//constructorExample();
		//invokeMethod();
		//invokeField();
		parserAnnotation();
		//arrayExample();
		//parserGeneric();
	}
	
	/**
	 * 获取类的Fields
	 */
	public static void fieldExample(){
		Student student = new Student();
		Class<?> studentClass = student.getClass();
		
		System.out.println("=================getFields()");
		Field [] fields = studentClass.getFields();
		for(Field f:fields){
			System.out.println(f);
		}
		
		System.out.println("\n=================getDeclaredFields()");
		fields = studentClass.getDeclaredFields();
		for(Field f:fields){
			System.out.println(f);
		}
	}
	/**
	 * 获取类的Method
	 */
	public static void methodExample(){
		Class<?> studentClass = Student.class;
		
		System.out.println("=================getMethods()");
		Method [] method = studentClass.getMethods();
		for(Method m:method){
			System.out.println(m);
		}
		
		System.out.println("\n=================getDeclaredMethods()");
		method = studentClass.getDeclaredMethods();
		for(Method m:method){
			System.out.println(m);
		}
		
		try {
			//按顺序声明setId()方法的类型已经个数
			//一个long类型的参数
			Class<?> [] parameterTypes = {long.class};
			//如果parameterTypes传递null,则按空数组处理
			Method m = studentClass.getMethod("setId", parameterTypes);
			System.out.println("获取getMethod(\"setId\", parameterTypes):"+m);
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取类的Constructor
	 */
	public static void constructorExample(){
		try {
			Class<?> studentClass = Class.forName("reflection.Student");
			
			System.out.println("=================getConstructors()");
			Constructor [] cons = studentClass.getConstructors();
			for(Constructor c:cons){
				System.out.println(c);
			}
			
			System.out.println("\n=================getDeclaredConstructors()");
			cons = studentClass.getDeclaredConstructors();
			for(Constructor c:cons){
				System.out.println(c);
			}

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过反射调用方法
	 */
	public static void invokeMethod() {
		
		try {
			Class<?> studentClass = Student.class;
			Object inst = studentClass.newInstance();
			
			Method setSubjectMethod = studentClass.getDeclaredMethod("setSubject", String.class);
			Object reObj = setSubjectMethod.invoke(inst, "计算机科学");
			System.out.println(reObj);
			
			Method getSubjectMethod = studentClass.getDeclaredMethod("getSubject", null);
			reObj = getSubjectMethod.invoke(inst, null);
			System.out.println(reObj);
			
			//invoke一个private方法
			Method privateMethod = studentClass.getDeclaredMethod("privateMethod", null);
			privateMethod.setAccessible(true);
			reObj = privateMethod.invoke(inst, null);
			System.out.println(reObj);

		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过反射设置字段
	 */
	public static void invokeField(){
		try {
			Class<?> studentClass = Student.class;
			Object inst = studentClass.newInstance();
			
			Field schoolNameField = studentClass.getDeclaredField("schoolName");
			schoolNameField.set(inst, "黑龙江大学");
			Object obj = schoolNameField.get(inst);
			System.out.println(obj);
			
			Field subjectField = studentClass.getDeclaredField("subject");
			subjectField.setAccessible(true);
			subjectField.set(inst, "计算机科学");
			obj = subjectField.get(inst);
			System.out.println(obj);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 读取注解
	 */
	public static void  parserAnnotation(){
		Class<?> stuClass = Student.class;
		Class<ElementDesc> annClass = ElementDesc.class;
	
		try {
			Object stuObj = stuClass.newInstance();
			
			if(stuClass.isAnnotationPresent(annClass)){
				ElementDesc elDesc = stuClass.getAnnotation(annClass);
				System.out.println("\n读取Student类上的ElementDesc注解:\n"+elDesc.value());
			}
			
			Constructor cons = stuClass.getDeclaredConstructor(long.class, int.class);
			if(cons.isAnnotationPresent(annClass)){
				ElementDesc elDesc = (ElementDesc) cons.getAnnotation(annClass);
				System.out.println("\n读取Student类构造方法上的ElementDesc注解:\n"+elDesc.value());
			}
			System.out.println("\n读取Student类构造方法形参上的ElementDesc注解:");
			Annotation [][] annss = cons.getParameterAnnotations();
			for(int i=0;i<annss.length;i++){
				Annotation[] anns = annss[i];
				if(anns.length==0) continue;
				Annotation ann = anns[0];
				if(ann instanceof ElementDesc){
					System.out.println( ((ElementDesc) ann).value() );
				}
			}
			
			System.out.println("\n读取Student类构造方法向形参类型:");
			Class [] parTypes = cons.getParameterTypes();
			Long ll = new Long(1L);
			for(Class c:parTypes){
				System.out.println("type name:"+c.getName());
			}
			
			
			Method method = stuClass.getDeclaredMethod("privateMethod", null);
			if(method.isAnnotationPresent(annClass)){
				ElementDesc elDesc = method.getAnnotation(annClass);
				System.out.println("\n读取Student类privateMethod()上的注解:\n"+elDesc.value());
			}
			
			Field field = stuClass.getDeclaredField("schoolName");
			if(field.isAnnotationPresent(annClass)){
				ElementDesc elDesc = field.getAnnotation(annClass);
				System.out.println("\n读取Student类schoolName字段上的注解:\n"+elDesc.value());
			}
			
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 读取泛型
	 */
	public static void parserGeneric(){
		Class arrListCls = ArrayList.class;
		try {
			
			TypeVariable<Class> [] classTypeVars = arrListCls.getTypeParameters();
			for(TypeVariable<Class> tv:classTypeVars){
				System.out.println(tv.toString());
				Type [] ts = tv.getBounds();
				Arrays.toString(ts);
				
			}
			
			Constructor<ArrayList<String>> cons = arrListCls.getConstructor(Collection.class);
			System.out.println( cons.toGenericString() );
			
			TypeVariable<Constructor<ArrayList<String>>> [] consTypeVars = cons.getTypeParameters();
			for(TypeVariable<Constructor<ArrayList<String>>> tv:consTypeVars){
				System.out.println(tv.toString());
			}
			
			Type [] types = cons.getGenericParameterTypes();
			for(Type t:types){
				System.out.println(t.toString());
			}
			
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	/**
	 * Array操作事例
	 */
	public static void arrayExample(){
		Object arr1 = Array.newInstance(String.class, 10);
		String [] arr2 = (String[]) arr1;
		for(int i=0;i<Array.getLength(arr2);i++){
			System.out.println(Array.get(arr2, i));
		}
		
		System.out.println("==========");
		
		Object arr3 = Array.newInstance(int.class, 10,2);
		int [][] arr4 = (int[][]) arr3;
		for(int i=0;i<Array.getLength(arr3);i++){
			int []arr5 = arr4[i];
			System.out.println( Arrays.toString(arr5) );
		}
	}
}
参考文章:
http://www.infoq.com/cn/articles/cf-java-generics
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值