Java 反射
Posted aston
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 反射相关的知识,希望对你有一定的参考价值。
一切皆为对象,是Java的核心概念;
从这个概念出发,我们不禁要问类是不是对象?如果类也是对象,类又是谁的实例对象呢?
答案是肯定的,类也是对象,类是java.lang.Class(以下简称Class)的实例对象,Class也被成为类的类类型。
假设有类Student,如下
class Student{ private int id; private String name; //get,set方法 }
获取类的类类型有三种方法,分别如下:
1. Class c1 = Student.class;
2. Student stu = new Student();
Class cl = stu.getClass();
3. Class cl = Class.forName("类全名");
我们可以通过类的类类型创建这个类的实例对象,前提是这个类有一个无参的构造函数,如下
Student stu = (Student) c1.newInstance();
动态加载的概念
编译时加载类是静态加载类,new 对象
运行时加载类时动态加载类
反射使用
//获取类的名称 String className = cl.getName(); //获取类名称的简写 String classSimpleName = cl.getSimpleName(); /** * Method类,方法的对象 * 一个成员方法就是一个Method对象 * getMethods() 获取的是全部public的方法,包括从父类继承来的 *getDeclaredMethods()获取自己声明的全部方法(public private protect),不获 * 取父类 */ Method[] methods = cl.getMethods(); for (Method method : methods){ //得到方法的返回类型 //得到方法返回值的类类型 Class returnType = method.getReturnType(); //得到方法名 String methodName = method.getName(); //获取参数类型 //得到参数列表的类型的类类型 Class[] paras = method.getParameterTypes(); for (Class c : paras){ System.out.print(c.getName()); } }
通过反射获取变量
/** * 成员变量也是对象 * java.lang.reflect.Field * Field 封装了成员变量的操作 * getFields() 获取所有的public成员变量信息 * getDeclaredFields() 获取该类自己声明的所有成员变量信息 */ Field[] fields = cl.getDeclaredFields(); for (Field field : fields){ //变量的修饰符 //得到成员变量的类型的类类型 Class fieldType = field.getType(); String typeName = fieldType.getName(); //得到成员变量的名称 String fieldName = field.getName(); //打印变量类型和变量名 System.out.println(typeName + " " + fieldName); }
打印构造函数信息
/** * 构造函数也是对象 * java.lang.reflect.Constructor 中封装了构造函数的信息 * getConstructors() 获取所有的public的构造函数 * getDeclaredConstructors() 获取所有的构造函数 */ /*Constructor[] cs = cl.getConstructors();*/ Constructor[] cs = cl.getDeclaredConstructors(); for (Constructor c : cs){ //获取构造函数名称 c.getName(); //获取构造函数的类型的类类型 c.getParameterTypes(); }
方法反射
/** * 方法的反射 * 方法的名称和方法的参数列表可以唯一确定一个方法 * 方法的反射操作 * Method.invoke(对象, 参数列表) */ public static void main(String[] args) throws Exception{ A a = new A(); //获取print(int, int)方法 //1. 首先获取类的类类型 Class cl = a.getClass(); /** * 2. 获取方法,名称和参数列表确定唯一方法 * getMethod() 获取的是public方法 * getDeclaredMethod() 获取全部自己声明的方法 */ Method method = cl.getMethod("print", new Class[]{int.class, int.class}); //3. 方法的反射操作,是指用Method对象来进行调用 //方法没有返回值返回null,有返回值就返回返回值 Object object = method.invoke(a, new Object[]{1,2}); //method.invoke(a, 1, 2); }
使用反射解析注解
//1.使用类加载器加载类 Class cl = Class.forName("Student"); //2.找到类上面的注解 boolean exist = cl.isAnnotationPresent(Customize.class); if (exist){ //3.拿到注解实例 Customize customize = (Customize) cl.getAnnotation(Customize.class); System.out.println(customize.value()); } //4.找到方法上的注解 Method[] methods = cl.getMethods(); for (Method method : methods){ if (method.isAnnotationPresent(Customize.class)){ System.out.println(((Customize)method.getAnnotation(Customize.class)).value()); } } //4.1另一种解析方法 for (Method method : methods){ Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations){ if (annotation instanceof Customize){ System.out.println(((Customize) annotation).value()); } } }
注解定义
public @interface Customize { String value() default "I am annotation"; }
以上是关于Java 反射的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)