美文网首页
java_反射

java_反射

作者: 老北瓜 | 来源:发表于2020-04-14 14:40 被阅读0次

反射: 框架设计的灵魂。

将类的各个组成部分封装成其他对象 就是反射机制。

java代码在计算机中经理的三个阶段

Source源代码阶段 Person.java -- (javac)--> Person.class

Class 类对象阶段 Person.class --(ClassLoader)--> 加载到内存中

Runtime 运行时阶段 new Person()

Class类对象

Class类中一般包含 成员变量(Field[ ] fields),构造方法(Constructor[ ] cons),成员方法(Method[ ] methods)分别将他们封装成括弧里面的对象
Class本身也是一个类
Class对象只能有系统建立对象
一个类在JVM中只会有一个Class实例,一个Class对象对应的是一个加载到JVM中的一个.class文件
每个类的实例都会记得自己是有哪个Class实例所生成
通过Class 可以正的得到一个类中的完整结构。

好处:
1,可以在程序运行过程中,操作这些对象
2,可以解耦,提高程序的可扩展性。

获取Class 对象的方式(对应三个阶段 )

1, 基本用这个
Class.forName("全类名"): 手动的将字节码文件加载进内存,返回Class对象 (多用于配置文件,将雷鸣定义在配置文件中,读取文件,加载类)

2,类名.class : 通过类名.class 获取 (多用于参数的传递)
3, 对象.getClass(), Object类中定义的。(多用于对象的获取字节码的方式)

4, 还有一个通过ClassLoader
ClassLoader cl = this.getClass().getClassLoader();
Class clazz =cl.loadClass("全类名");

  • 同一个字节码文件再一次程序运行过程中,只会被加载一次,上面三种方式获取到的Class 对象都是同一个。

Class对象功能:
获取功能
1,获取成员变量们

image.png
  private static void method3() {
        try {
            Class clazz = Class.forName("com.bg.collections.fanshe.Student");

            // 拿到所有共有的属性, 包括父类的属性
            Field[] fields = clazz.getFields();

            // 拿到所有属性,但是不包括父类的属性
//            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                System.out.println("属性的名字:" + field.getName());
                System.out.println("属性的类型:" + field.getType());

                System.out.println("=================");
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

getFiled() 获取所有public 修饰的成员变量
getFiled(String name) 获取指定的public 修饰的成员变量

获取到Field 可做的操作 就是 获取值 和 设置值

2, 获取构造方法们 image.png getParameterTypes() 构造放大方法的 参数类型
3, 获取成员方法们 image.png
private static void method2() {
        try {
            Class clazz = Class.forName("com.bg.collections.fanshe.Student");

            // 拿到全部的共有方法
            Method[] methods = clazz.getMethods();

            // 拿到全部的方法,包括私有方法;
            Method[] declaredMethods = clazz.getDeclaredMethods();

            for (Method method : methods) {
                System.out.println("方法名:" + method.getName());
                System.out.println("返回值类型:" + method.getReturnType());
                Class[] pes = method.getParameterTypes();
                if (pes != null && pes.length > 0) {
                    for (Class pe : pes) {
                        System.out.println("参数类型:" + pe.getName());
                    }
                }
                System.out.println("=============================");
            }


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

4, 获取类名
cls.getName()

5,获取接口
cls.getInterfaces()

通过反射的方法来创建对象

 private static void method1() {
        try {
            Class cls = Class.forName("com.bg.collections.fanshe.Student");

            //调用的无参构造方法
            Constructor c1 = cls.getConstructor();
            Student stu1 = (Student) c1.newInstance();
            System.out.println();

            // 这是拿到 Student(String school) 的构造方法。
            Constructor c2 = cls.getConstructor(String.class, int.class);
            Student stu2 = (Student) c2.newInstance("我的奋斗", 20);
            System.out.println("执行的是公有构造方法Student(String name,int age)");

            //强制调用私有构造方法;
            Constructor c3 = cls.getDeclaredConstructor(String.class);
            // 破除私有封装,下面就可以强制调用私有构造方法。
            c3.setAccessible(true);
            Student stu3 = (Student) c3.newInstance("我的学校");
            System.out.println("调用的是私有的构造方法 Student(String school)");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

通过反射调用指定方法:

 /**
     * 通过反射调用指定的方法
     */
    private static void method4() {
        try {
            Class clazz = Class.forName("com.bg.collections.fanshe.Student");
            Constructor c = clazz.getConstructor();
            Object obj = c.newInstance();

            //调用public指定方法
            Method setInfo = clazz.getMethod("setInfo", String.class, String.class);
            setInfo.invoke(obj, "小明", "高中");

            // 调用有返回值的public 指定方法;
            Method getSchool = clazz.getMethod("getSchool");
            String school = (String) getSchool.invoke(obj);
            System.out.println("school = " + school);

            // 调用 private 指定方法
            Method setX = clazz.getDeclaredMethod("setX");
            setX.setAccessible(true);
            setX.invoke(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

通过反射调用指定属性:

 /**
     * 通过反射调用指定的属性 ;
     */
    private static void method5() {
        try {
            Class clazz = Class.forName("com.bg.collections.fanshe.Student");

            Constructor con = clazz.getConstructor();
            Student student = (Student) con.newInstance();

            //调用公有属性 clas
            Field field = clazz.getField("clas");
            field.set(student, 23);
            System.out.println("调用公有属性 clas = " + field.get(student));


            //调用私有属性 school;
            Field f = clazz.getDeclaredField("school");
            f.setAccessible(true);
            f.set(student, "高中");
            System.out.println("调用私有属性 school = " + f.get(student));


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Java 的动态代理

Proxy: 专门完成代理的操作类,是所有动态代理类的父类。通过此类为一个或多个接口动态的生成实现类。
创建一个动态代理类所对应的Class对象
场景
一个java项目,其中有100个java类,没个java类有10个方法,现在有个需求,需要在没个java方法上加两句话,在方法执行前 System.out.print("方法开始执行"); 在方法执行后 System.out.print("方法执行完毕");

.................太难了.................

相关文章

  • java_反射

    1 ,什么是java反射:是一种运行时机制,在运行过程中,能获取类的属性和方法,对于对象能调用任意的方法,动态获取...

  • java_反射

    反射: 框架设计的灵魂。 将类的各个组成部分封装成其他对象 就是反射机制。 java代码在计算机中经理的三个阶段 ...

  • java_反射、动态代理

    基本用法 Java 反射API的第一个主要作用是获取程序在运行时刻的内部结构。这对于程序的检查工具和调试器来说,是...

  • Java书籍资料整理

    http://en.wikipedia.org/wiki/Template:Java_%28software_pl...

  • 雪花算法

    雪花算法的原理和实现Java_雨夜青草的博客-CSDN博客_雪花算法 64 = 1 41 10 12

  • alibaba-nacos-config 阿里的nacos

    参见:SpringBoot使用Nacos作为配置中心服务和服务注册中心_java_牧竹子-CSDN博客 手册参见:...

  • java_多线程

    java_多线程 线程创建方式;join用法; sleep和wait区别; 线程安全和不安全的java集合; St...

  • Java 调用jni方法

    两种实现方式 Java_包名类名方法名 RegisterNatives方法 native 方法如下 第一种方式:在...

  • java_集合

    参考https://www.cnblogs.com/NextNight/p/6972172.html 关系图 Ha...

  • JAVA_代理

    代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。通过代理,可以实现对目标对象的间...

网友评论

      本文标题:java_反射

      本文链接:https://www.haomeiwen.com/subject/jmxnphtx.html