• 15-1 Java反射机制概述


    Java Reflection

    • Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
    • 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射
      在这里插入图片描述

    补充:动态语言 vs 静态语言

    1. 动态语言
      是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构
      主要动态语言:Object-C、C#、JavaScript、PHP、Python、Erlang
    2. 静态语言
      与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java、C、C++

    Java不是动态语言,但Java可以称之为“准动态语言”。即Java有一定的动态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性。Java的动态性让编程的时候更加灵活!


    Java反射机制研究及应用

    Java反射机制提供的功能

    在运行时判断任意一个对象所属的类
    在运行时构造任意一个类的对象
    在运行时判断任意一个类所具有的成员变量和方法
    在运行时获取泛型信息
    在运行时调用任意一个对象的成员变量和方法
    在运行时处理注解
    生成动态代理


    反射之前,类的实例化操作

    Person类

    public class Person {
    
        private String name;
        public int age;
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        private Person(String name) {
            this.name = name;
        }
    
        public Person() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public void show(){
            System.out.println("你好,perosn");
        }
    
        public String showNation(String nation){
            System.out.println("我的国籍是:"+nation);
            return nation;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    反射之前,对于Person的操作

    //反射之前,对于Person的操作
        @Test
        public void test(){
    
            //1.创建类的对象
            Person p1 = new Person("Tom",12);
    
            //2.调用对象,调用其内部的属性和方法
            p1.age = 15;
            System.out.println(p1.toString());
    
            p1.show();
    
            //在Person类的外部,不可以通过Person类的对象调用其内部私有的结构。
            //比如:name、showNation以及私有的构造器。
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    反射之后 ,对于Person的操作

     //反射之后 ,对于Person的操作
        @Test
        public void test2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
            Class clazz = Person.class;
            //1.通过反射,创建Person类的对象
            Constructor cons = clazz.getConstructor(String.class,int.class);
            Object obj = cons.newInstance("Tom",12);
            Person p = (Person) obj;
            System.out.println(p.toString());
            //2.通过反射,调用对象指定的属性和方法
            //调用属性
            Field age = clazz.getDeclaredField("age");
            age.set(p,10);
            System.out.println(p.toString());
    
            //调用方法
            Method show = clazz.getDeclaredMethod("show");
            show.invoke(p);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    反射的强大,调用类的私有结构

        @Test
        public void test2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
            Class clazz = Person.class;
            //1.通过反射,创建Person类的对象
            Constructor cons = clazz.getConstructor(String.class,int.class);
            Object obj = cons.newInstance("Tom",12);
            Person p = (Person) obj;
            System.out.println(p.toString());
            //2.通过反射,调用对象指定的属性和方法
            //调用属性
            Field age = clazz.getDeclaredField("age");
            age.set(p,10);
            System.out.println(p.toString());
    
            //调用方法
            Method show = clazz.getDeclaredMethod("show");
            show.invoke(p);
    
            System.out.println("***********************************************");
    
            //通过反射,是可以调用Person类的私有结构的。比如:私有的构造器、方法、属性
            //调用私有的构造器
            Constructor cons1 = clazz.getDeclaredConstructor(String.class);
            cons1.setAccessible(true);
            Person p1 = (Person) cons1.newInstance("Jerry");
            System.out.println(p1);
    
            //调用私有的属性
            Field name = clazz.getDeclaredField("name");
            name.setAccessible(true);
            name.set(p1,"HanMeiMei");
            System.out.println(p1);
    
            //调用私有的方法
            Method showNation = clazz.getDeclaredMethod("showNation", String.class);
            showNation.setAccessible(true);
            String nation = (String) showNation.invoke(p1,"china");
            //相当于String nation = p1.showNation("china")
            System.out.println(nation);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    如何看待封装和反射?

    /**
    * 疑问1:通过直接new的方式或反射的方式都可以调用公共的结构,开发中到底用那个?
    * 建议:直接new的方式。
    * 什么时候会使用:反射的方式。 反射的特征:动态性
    * 疑问2:反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?
    * 不矛盾。
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    机器学习——代价敏感错误率与代价曲线
    利用kubeadmin快速搭建kubenates集群
    Python编程实例-Matplotlib实时数据可视化
    为K8S集群准备Ceph存储
    el form 表单validate成功后没有执行逻辑
    SpringCloud - Spring Cloud 之 Zuul和Gateway网关(十四)
    算法题练习——NC45 实现二叉树先序,中序和后序遍历,NC119 最小的K个数
    R语言地理加权回归、主成份分析、判别分析等空间异质性数据分析
    智能手术机器人起源及应用(一)
    【JavaScript 进阶教程】非 extends 的组合继承
  • 原文地址:https://blog.csdn.net/qq_44774198/article/details/125993000