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");
        }
  • 相关阅读:
    Android的各版本间的区别总结
    深入浅出Android开发之Surface介绍
    android中完全退出当前应用程序的四种方法
    android离线地图源码
    坐标系
    mysql安装
    linux磁盘空间清理
    HttpClient教程
    TIME_WAIT过多
    c3p0配置详解
  • 原文地址:https://www.cnblogs.com/woyaobianfei/p/9330789.html
Copyright © 2011-2022 走看看