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);
}

使用反射回去对象变量值

public static <T> void printTInfo(T t) throws IllegalAccessException{
        Class cl = t.getClass();

        Field[] fields = cl.getDeclaredFields();
        for (Field field : fields){
            //setAccessible(true)不总是必须的,但是变量为私有是必须设置
            field.setAccessible(true);
            System.out.println(field.get(t));
        }
}

使用反射解析注解

//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());
               }
       }
}

注解定义

长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn