• 反射机制


    反射的定义

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

    反射机制可以获取的功能

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

    这里不多说直接看代码

    //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)//获得方法的自定义注解

    努力到无能为力,拼搏到感动自己
  • 相关阅读:
    判断字符串是否为空
    NameVirtualHost *:80 has no VirtualHosts
    angular笔记
    Angular *ngIf length
    angular 8 表单带文件上传接口
    angular8 大地老师学习笔记---第十课
    angular8 大地老师学习笔记---第九课
    angular8 大地老师学习笔记---第八课
    angular8 大地老师学习笔记---第六课
    记录一下网上找到的别人写的angualr总结
  • 原文地址:https://www.cnblogs.com/tkzm/p/11052323.html
Copyright © 2020-2023  润新知