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.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