zoukankan      html  css  js  c++  java
  • Java反射机制

    1.反射定义:
    Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。

    2.反射作用:
    取得任何一个已知名称的class的内部信息。

    3.Class对象:
    每个类都会产生一个对应的Class对象,也就是保存的.class文件。所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员的引用时,就会加载这个类。Class对象仅在需要的时候才会加载,static初始化是在类加载时进行的。

    类加载器首先会检查这个类的Class对象是否已被加载过,如果尚未加载,默认的类加载器就会根据类名查找对应的.class文件。

    想在运行时使用类型信息,必须通过Class对象获取,使用功能Class.forName(“对象名或者对象名.class”)。
    注意:使用功能”.class”来创建Class对象的引用时,不会自动初始化该Class对象,使用forName()会自动初始化该Class对象。一个类在 JVM 中只会有一个 Class 实例

    为了使用类而做的准备工作一般有以下3个步骤:
    加载:由类加载器完成,找到对应的字节码,创建一个Class对象
    链接:验证类中的字节码,为静态域分配空间
    初始化:如果该类有超类,则对其初始化,执行静态初始化器和静态初始化块

    4.方法
    通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等
    查阅 API 可以看到 Class 有很多方法:
      getName():获得类的完整名字。
      getFields():获得类的public类型的属性。
      getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
      getMethods():获得类的public类型的方法。
      getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
      getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
      getConstructors():获得类的public类型的构造方法。
      getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
      newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
           invoke():打破封装。
    5.例子

    package com.test.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Test_Reflect {
        public  int age;
        private String name;
        private String sex;
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public Test_Reflect(int age, String name, String sex) {
            super();
            this.age = age;
            this.name = name;
            this.sex = sex;
        }
    
        public Test_Reflect() {
            super();
        }
    
        public static void main(String[] args) throws Exception {
            Test_Reflect tr=new Test_Reflect();
            Class c = Class.forName("com.test.reflect.Test_Reflect");
            //Class c=tr.getClass();
            String className = c.getName();
            System.out.println(className);
    
            // 获得public属性
            Field[] fields = c.getFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }
    
            // 获得所有属性(包括私有)
            Field[] allFields = c.getDeclaredFields();
            for (Field field : allFields) {
                System.out.println(field.getName());
            }
    
            // 获得public方法,包括 Object 类的一些方法
            Method[] methods = c.getMethods();
            for (Method method : methods) {
                System.out.println(method.getName());
            }
            
            // 获得所有方法
            Method[] allMethods = c.getDeclaredMethods();
            for (Method method : allMethods) {
                System.out.println(method.getName());
            }
    
            // 获得指定属性
            Field f1 = c.getField("age");
            System.out.println(f1);
            // 获得指定私有属性
            Field f2 = c.getDeclaredField("name");
            // 启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
            f2.setAccessible(true);
            System.out.println(f2);
    
            // 创建类的对象
            Object p2 = c.newInstance();
            // 将 p2 对象的 f2 属性赋值为 Tom,f2 属性即为 私有属性 name
            f2.set(p2, "Tom");
            // 使用反射机制可以打破封装性,导致了java对象的属性不安全。
            System.out.println(f2.get(p2));
    
            // 获取构造方法
            Constructor[] constructors = c.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor.toString());
            }
        }
    }

    6.使用场景
    JDBC原生代码注册驱动,hibernate 的实体类,Spring 的 AOP,逆向代码 ,例如反编译,与注解相结合的框架 例如Retrofit,单纯的反射机制应用框架 例如EventBus 2.x,动态生成类框架 例如Gson等

  • 相关阅读:
    pyecharts的版本问题
    世界各国中英文名称映射字典(pyecharts)
    爬取世界疫情数据绘制疫情可视化地图
    好好写,好好干-PHP基础(二)
    自罚一杯-PHP基础(一)
    又是一周-AJAX(三)
    我懒蛋又回来了!-PDO
    退役了退役了-AJAX
    睡觉问题早晚成为我顶头疼的问题。。。-PHP
    其实今天没有欲望..-MySQLi
  • 原文地址:https://www.cnblogs.com/ericz2j/p/10255980.html
Copyright © 2011-2022 走看看