java反射机制学习笔记
2017-03-02 16:47
405 查看
java反射机制学习笔记
计划想系统的学习一下java反射机制、注解知识,然后自己实现一个ORM框架来加深和巩固对这部分知识的理解。本片文章对java反射机制常用的API进行了总结,并提供了一个代码事例来理解java反射API。java反射机制总结
如果看不清图片,请鼠标右键选择在新标签也打开。这张思维导图并没有用连接线关联出它们之间的继承关系,但是有几个重要的继承和实现关系我们需要知道。
Class类实现了以下接口:
java.io.Serializable;用于序列化
java.lang.reflect.GenericDeclaration;读取泛型
java.lang.reflect.Type;读取泛型
java.lang.reflect.AnnotatedElement:用于读取注解
Constructor<T>和Method类实现了以下接口:
java.lang.reflect.GenericDeclaration;读取泛型
java.lang.reflect.Member;获取方法名字、访问修饰符等相关信息
继承了以下类:
java.lang.reflect.AccessibleObject;取消默认的java语言控制访问检查能力
Field类实现了以下接口:
java.lang.reflect.Member;获取字段名字、访问修饰符等相关信息
继承了一下类:
java.lang.reflect.AccessibleObject;取消默认的java语言控制访问检查能力
AccessibleObject类继承了以下类:
java.lang.reflect.AnnotatedElement;用于读取注解
java反射这一部分对泛型的读取以及读取泛型的用途还没有搞清楚,希望在以后的应用中能接触到并搞懂。
java反射代码事例
CleverAnimal.javapackage 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
http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/builds/latest/html/zh_CN/api/
相关文章推荐
- JAVA反射机制初步学习笔记
- 黑马程序员_java反射机制的学习笔记
- Java反射机制学习笔记
- 尚硅谷java学习笔记——13.java反射机制
- java反射机制学习笔记
- 黑马程序员——学习笔记14.Java反射机制
- 黑马程序员_Java反射机制学习笔记
- [学习笔记]Java反射机制
- Java反射机制学习笔记
- Thinking in Java---类型信息和java反射机制学习笔记
- Java反射机制学习笔记
- java反射机制学习笔记与Method类invoke方法jvm底层优化方案
- java反射机制学习笔记
- Java反射机制学习笔记
- Java反射机制学习笔记(一)
- Java反射机制学习笔记
- java反射机制学习笔记及例子代码
- 学习笔记_java反射机制
- Java反射机制-学习笔记2
- Java反射机制学习笔记