zoukankan      html  css  js  c++  java
  • java 反射

    1, Class 可以理解是字节码对象

    2, 不使用源码获取到类的信息, 比如方法, 成员变量等

    获取的途径

    下面三种效果是一样的, 只是泛型不一样

    // 1, 类.class
    Class<User> userCls = User.class;
    // 2, 对象.getClass()
    Class<? extends User> userCls2 = new User().getClass();
    // 3, Class.forName("类的全路径")
    Class<?> userCls3 = Class.forName("com.study.User");

    获取构造方法

    // 获取所有构造方法
    Constructs[] constructors = User.getConstructors();
    // 获取具体构造方法
    User user = new User();
    Constructor<User> constructor = userCls1.getConstructor(String.class, int.class);

    创建对象(执行构造方法)

    // 执行一个有参的构造方法创建对象
    User user = constructor.newInstance("Marry", 20);
    // 执行无参的构造创建对象, 如果是无参构造, 可以省去获取构造方法这一步骤
    User user2 = User.class.newInstance()

    获取字段

    Class<User> userCls = User.class;
    // 获取所有字段, 返回一个字段数组
    Field[] fields = userCls.getDeclaredFields();
    for (Field f : fields) {
        String fieldName = f.getName();
        System.out.println(fieldName);
    }
    // 获取指定的字段
    Field field = userCls.getField("name");

    获取字段值

    // 获取构造方法
    Constructor<User> constructor = userCls1.getConstructor(String.class, int.class);
    // 创建一个对象
    User user = constructor.newInstance("Marry", 20);
    // 获取指定的字段
    Field field = User.class.getDeclaredField("username");
    // 暴力反射, 用于获取非公开变量
    field.setAccessible(true);
    // 指明获取字段值的目标对象
    String username = (String) field.get(user);
    System.out.println(username);

    设置/修改字段值

    // 获取构造方法
    Constructor<User> constructor = userCls1.getConstructor(String.class, int.class);
    // 创建一个对象
    User user = constructor.newInstance("Marry", 20);
    // 获取指定的字段
    Field field = User.class.getDeclaredField("username");
    // 只是设置不需要暴力反射, 获取需要, 既获取又设置也需要
    field.setAccessible(true);
    // 设置新的值, 原本是 Marry
    field.set(user, "Bob");
    // 获取
    String username = (String) field.get(user);
    System.out.println(username);

    获取类的方法

    // 获取所有方法
    Method[] methods = User.class.getDeclaredMethods();
    // 获取指定方法
    Method method = User.class.getMethod("setUsername", String.class);
    // 获取 Stirng 类的 replaceAll 方法
    Method method2 = String.class.getMethod("replaceAll", String.class, String.class);

    执行方法

    // 执行方法, 也需要指明对象, 第一个参数是目标对象, 第二个参数是执行方法的参数
    method.invoke(user, "Rose");
    // 如果是私有方法需要放开权限(暴力反射)
    method.setAccessible(true);
    // 参数可以是可变参数, 也可以是数组: "hello word".replaceAll("o", "a")
    String str2 = (String) method2.invoke("hello word", "o", "a");
  • 相关阅读:
    在使用IO流时该选择何种流对象
    对Java中的File类的一些理解
    AlarmManager实现闹钟功能
    Android 中 Movie 类显示GIF图片
    Java对象序列化和serialVersionUID [转载]
    Git常用命令行操作
    Android中常用的编码和解码(加密和解密)的问题
    Android apk反编译 和 防止反编译
    Bitmap 图片二次采样 【转载】
    Android:瀑布流效果 的简单实现
  • 原文地址:https://www.cnblogs.com/huanggy/p/9826455.html
Copyright © 2011-2022 走看看