zoukankan      html  css  js  c++  java
  • 反射学习总结 --为理解SpringMVC底层做准备

    反射是什么?

      通俗理解 - 照X光。

      java:一个类在反射面前就像照X光,清清楚楚明明白白。

      应用:我们的ide中,能够"."一下就知道类中的所有方法就是通过反射实现的。

         XML中配置的class全路径动态生成类。(框架)

      程序在运行过程中,动态的创建对象。

        -- 只要知道类的名称,就可以利用他的字节码对象来创建该类的一个对象。

    何为class对象:

      HelloWorld.java

      通过 javac HelloWorld.java   ----->HelloWorld.class(字节码文件) ---> java HelloWorld    jvm把HelloWorld.class加载到内存中,变成Class对象

      

    关于Class的加载:

    public static void main(String[] args) {
            Person p = new Person();
            Class pClassclass = p.getClass();
            System.out.println(pClassclass);
            Person person = new Person("aa", "18", "USA");
            Class personClass  = person.getClass();
            System.out.println(personClass);
            System.out.println(pClassclass == personClass); //true 字节码文件在程序运行过程中,只会被加载到内存中一次
        }
    

      

    获取Class的三种方法: p.getClass(),  Person.class,  Class.forName("类名全路径")

    public static void main(String[] args) throws ClassNotFoundException {
            Person p = new Person();
            Class p1 = p.getClass();
            Person person = new Person("aa", "18", "USA");
            Class p2  = person.getClass();
            System.out.println(p1 == p2);
            Class<Person> p3 = Person.class;
            System.out.println(p3 == p1);
            Class<?> p4 = Class.forName("com.java.demo.clazz.Person");
            System.out.println(p4 == p3);
        }

    无论是哪一种,字节码都只有一个

    使用Class

      先看下类和字节码对象的关系

      

    关于构造方法:

      方式一:用newInstance()方法

      class.newInstance(),时,newInstance()底层需要调用无参的构造方法,所以,我们被反射的类中,需要有一个无参的构造方法

        public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
            //通过字节码对象,创建一个对象
            Class<?> aClass = Class.forName("com.java.demo.clazz.Person");
            Person person = (Person) aClass.newInstance();
    
        }

      方式二:用Constructor, 这个时候,空参的构造方法就是非必须的了。

        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            Class<?> aClass = Class.forName("com.java.demo.clazz.Person");
            Constructor<?> constructor = aClass.getConstructor(String.class, String.class,String.class);
            Person instance = (Person)constructor.newInstance("aa", "18", "USA");
        }

      方式二的增强版:当用的是getDeclaredConstructor()方法,setAccessible(true)之后,就算他的构造方法是private的也能创建对象(他能获取到所有的东西,包括公共的私有的)

        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            Class<?> aClass = Class.forName("com.java.demo.clazz.Person");
            Constructor<?> constructor = aClass.getDeclaredConstructor(String.class, String.class,String.class);
            constructor.setAccessible(true); //暴力访问 IllegalAccessException
            Person instance = (Person)constructor.newInstance("aa", "18", "USA");
        }

    获取Field(成员变量)

      只要是Declared的,就能获取到所有声明的变量

    public static void main(String[] args) {
            Class<Person> personClass = Person.class;
            Field[] fields = personClass.getFields(); //这种只能获取到公共的
            for (Field f : fields) {
                System.out.println(f);
            }
            Field[] declaredFields = personClass.getDeclaredFields(); //这种可以获取到所有的
            for (Field f : declaredFields) {
                System.out.println(f);
            }
        }

    获取Method(类中的方法)

      只要是Declared的,就能获取到所有声明的方法

     public static void main(String[] args) {
            Class<Person> personClass = Person.class;
            Method[] declaredMethods = personClass.getDeclaredMethods();
            for (Method method : declaredMethods){
                System.out.println(method);
            }
        }

      Method方法的调用

        public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
            Class<Person> personClass = Person.class;
            Person person = personClass.newInstance();
            Method spark = personClass.getDeclaredMethod("spark",String.class);
            //执行方法,invoke, 两个参数
            //第一个参数method属于那个对象,第二个对象方法参数
            spark.setAccessible(true);
            spark.invoke(person,"HeLLO GRIL");
        }
  • 相关阅读:
    Mac安装LightGBM
    用于视频超分辨率的可变形三维卷积
    ORB-SLAM3 单目地图初始化(终结篇)
    重用地图的单目视觉惯导SLAM系统
    2020,我的秋招感悟!
    超详细解读ORB-SLAM3单目初始化(下篇)
    基于改进的点对特征的6D位姿估计
    深入研究自监督单目深度估计:Monodepth2
    ORB-SLAM3 细读单目初始化过程(上)
    基于视觉和惯性传感器的移动机器人手遥操作系统
  • 原文地址:https://www.cnblogs.com/woyaobianfei/p/9330789.html
Copyright © 2011-2022 走看看