zoukankan      html  css  js  c++  java
  • 反射机制

    反射的定义

    反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性

    反射机制可以获取的功能

    • 在运行时获取类的修饰符,包名,类名,实现的接口,继承的父类
    • 在运行时获取类的所有属性名,修饰符,属性类型
    • 在运行时获取所有方法,方法的返回值类型,方法名,方法参数数量,方法参数类型
    • 在运行时调用加载类的方法

    这里不多说直接看代码

    //class类:不同的字节码信息,我们发现有共同的特点,所以可以看做是同一个类下的不同对象。我们将它进行向上抽取的类:Class类
            //获取Class类的对象(一共三种方式),   获取字节码信息
            //方式1:getClass()
            Student s1=new Student();
            Class c1 = s1.getClass();//方式2
            Class c3=Student.class;
    //方式1、2两种方式很少调用
            //方式3
            Class c5=Class.forName("Lx1.Student");
    //已经可以获取类的字节码信息
            System.out.println("类的全称:"+c5.getName());
            System.out.println("类的简称:"+c5.getSimpleName());
            System.out.println("类的修饰符:"+c5.getModifiers());
            //类的修饰符:17对应的数字 去Modifier类中查找 将16进制转为十进制
            System.out.println("显示看修饰符"+Modifier.toString(c5.getModifiers()));
            //查看父类
            System.out.println(c5.getSuperclass().getName());

              System.out.println("该类实现的接口有:");
              Class[] classes = clazz.getInterfaces();
              for (Class class1 : classes) { //Class:数组元素的类型 class1:数组中的每个元素 : classes要遍历的数组
              System.out.print(class1.getSimpleName()+",");

    Class c1=Class.forName("Lx2.Student");
            //c1   Student字节码信息
            //可以创建对象  newInstance()  调用的是public修饰的空构造器
            c1.newInstance();
            //没有空构造器  会有异常
            //构造器私有   也会报异常
            //获取构造器    private修饰的构造器这种方式获取不到
    //获取指定的构造器
            //获取指定的空构造器
            Constructor con2=c1.getConstructor();
            System.out.println(con2);
            //获取四个参数的构造器  注意参数类型是class
            System.out.println("***************");
            Constructor con3=c1.getConstructor(double.class,double.class,int.class,char.class);

              con3.setAccessible(true);//解除private障碍
              Object o3 = con4.newInstance(1.6,2.8,19,'女');
              System.out.println(o3); 

    //获取所有方法  包括父类
            Method[] ms = c1.getMethods();
            for (Method m : ms) {
                System.out.println(m);
            }
            System.out.println("方法的个数:"+ms.length);
            //获取Student全部方法
            System.out.println("----------");
            Method[] ds = c1.getDeclaredMethods();
            for (Method m : ds) {
                System.out.println(m);
            }
            System.out.println("方法的个数:"+ds.length);
            
            //获取指定的方法
            Method m1=c1.getMethod("toString");
            System.out.println(m1);
            System.out.println("方法的名字:"+m1.getName());
            System.out.println("方法的修饰符:"+Modifier.toString(m1.getModifiers()));
            System.out.println("方法的返回值类型:"+m1.getReturnType().getSimpleName());
            System.out.println("方法的参数:"+Arrays.toString(m1.getParameterTypes()));
            
            System.out.println("-------------------------");
            Method m2=c1.getMethod("setClassid",int.class);
            System.out.println(m2);
            System.out.println("方法的名字:"+m2.getName());
            System.out.println("方法的修饰符:"+Modifier.toString(m2.getModifiers()));
            System.out.println("方法的返回值类型:"+m2.getReturnType().getSimpleName());
            System.out.println("方法的参数:"+Arrays.toString(m2.getParameterTypes()));
            
            
            //执行方法
            Student s=(Student)c1.newInstance();
            System.out.println(m1.invoke(s));
    //获取所有成员变量
        public static void getFields(Class clazz) throws Exception{
            //单数和复数形式的方法 getField getDeclaredField(单个)  加s获取所有
            // getField获取非私有字段 getDecalredField操作私有
            Field[] fields = clazz.getDeclaredFields();
            
            for (Field field : fields) {
                System.out.println(Modifier.toString(field.getModifiers())+" "
                                   +field.getType().getSimpleName()+" "+field.getName());
            }
    
            Field field = clazz.getDeclaredField("age");
            //与通过new关键字创建的实例对象一样
            Object obj = clazz.newInstance();
            //屏蔽字段的私有特性
            field.setAccessible(true);
            field.set(obj, 16);
            
            Student stu=(Student)obj;
            
            System.out.println(stu.getAge());            
        }
    //反射获得注解
        public static void getAnnotation(Class clazz) throws Exception{
            StudentAnnotation annotation =(StudentAnnotation)clazz.getAnnotation(StudentAnnotation.class);
            System.out.println("学生类:"+annotation.studentname()+",学号:"+annotation.studentNo());
            StudentAnnotation annotation2 = clazz.getDeclaredField("stuname").getAnnotation(StudentAnnotation.class);
            System.out.println("学生姓名字段:"+annotation2.studentname()+",学号:"+annotation2.studentNo());
            StudentAnnotation annotation3=clazz.getDeclaredMethod("talk").getAnnotation(StudentAnnotation.class);
            System.out.println("自我介绍方法:"+annotation3.studentname()+",学号:"+annotation3.studentNo());
        }
    //自定义注解

    //在Java中的任何一个注解都离不开JDK的四个原注解

      //1.@Target(当前注解的使用范围) 2.@Documented(API的帮助文档) 3.@Retention(注解类型) 4.@inherited(继承)

    @Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface StudentAnnotation {
         String studentname();
         String studentNo();
    }

    //可以这样使用
    @StudentAnnotation(studentname="张三",studentNo="00001")

    总结:

    将类结构转换为Class类的实例可以用的方法

    1. 类名.class
    2. new 类名.getClass()
    3. Class.forName(String className)

    获取指定类继承的父类包括实现的接口

    变量名.getSuperclass().getSimpleName()//获取父类的简单名称

    变量名.getInterfaces()//获取所有接口

    获取访问修饰符 

     Modifier.toString(变量名.getModifiers())

     获取所有成员变量

    getField(String name)//获取单个成员变量(只能获取到非私有的

    getFields()//获取所有成员变量(只能获取到非私有的

    getDeclaredFields()//获取所有成员变量(都可以获取包括private

    getDeclaredField()//获取单个成员变量(都可以获取包括private

    newInstance()//与通过new关键字创建的实例对象一样

    setAccessible(true)//屏蔽字段私有性

    getType().getSimpleName()//获取简单的变量类型

    获取所有成员方法

     getMethods()//所有的方法,包括父类

     getMethods()//获取单个方法,括号里面传的是不定长参数

     getDeclaredMethods()//获取当前类的所有方法,不包含父类

     getDeclaredMethod()//获取当前类的单个方法,括号里面传的是不定长参数

     getParameterTypes()//获取方法的参数

     getReturnType()//返回值类型

     invoke()//执行方法

     获取构造函数

     getConstructor()//获取指定参数的构造函数,括号里传的是不定长参数,类型后面不要忘记加class

     constructor.newInstance()//给获取到的单个构造函数赋值

     getConstructors()//获取所有的构造函数

     获取自定义注解

    getAnnotation(自定义注解.class)//获得class注解,括号里面传的是自定义注解,注意不要忘记加class

    getDeclaredField(成员变量).getAnnotation(自定义注解.class)//获得成员变量的自定义注解

    getDeclaredMethod(成员方法).getAnnotation(自定义注解.class)//获得方法的自定义注解

    努力到无能为力,拼搏到感动自己
  • 相关阅读:
    JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
    有空必看
    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换
    FusionCharts JavaScript API Column 3D Chart
    FusionCharts JavaScript API
    FusionCharts JavaScript API
    Extjs 继承Ext.Component自定义组件
    eclipse 彻底修改复制后的项目名称
    spring 转换器和格式化
    Eclipse快速生成一个JavaBean类的方法
  • 原文地址:https://www.cnblogs.com/tkzm/p/11052323.html
Copyright © 2011-2022 走看看