您的位置:首页 > 编程语言 > Java开发

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

http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/builds/latest/html/zh_CN/api/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Class java反射机制