大白话 | Java初学指♂男:“说说初学的误区与死结”( 壹 | 反射与Field )

思考

通常,我们这么给变量赋值:

String name = "XiaoMing";
name = "DaMing";

那么假如,我们不允许直接给name这个变量赋值,但我们提供与该变量名相同的字符串

String name = "XiaoMing";

// variable 中指定了要修改的变量
String variable = "name";

// 将 variable 中指定的变量修改为 value 的值
String value = "DaMing";

// 不允许使用以下方法直接给 name 赋值:
// name = value;
// name = "DaMing";
// 要求最终, name 的值为 DaMing

题目要求:

  1. 根据variable变量中的字符串name,找到和字符串名字相同的变量
  2. variable字符串中指定变量的值修改为DaMing
  3. 必须依靠字符串来修改该变量的值,而不是直接赋值
  4. 最终,变量name的值应该是DaMing,而不应该去修改变量variable的值

实例

想好了吗?让我们来看看下方的题解:

public class Main {
    // 定义 name 为静态变量,在启动时就被定义
    public static String name = "XiaoMing";

    public void Test() {
        try {

            System.out.println("修改前,name的值为:" + name);

            String variable = "name";
            String value = "DaMing";

            // 获取 name 所在 Main 类的 Class 反射
            Class clazz = Main.class;

            // 通过getDeclaredField(String 变量名) 可以获得该类中指定变量的操作权
            // 而 Field 就可以提供对变量的操作
            Field field = clazz.getDeclaredField(variable);
	    // 也可以写为:
	    // Field field = clazz.getDeclaredField("name");

            // 使用 field.set(Class反射类, 值) 可以将该变量修改为指定值
            field.set(clazz, value);
            // 也可以写为:
            // field.set(clazz, "DaMing");

            System.out.println("修改后,name的值为:" + name);

        } catch (Exception e) {}
    }

    public static void main(String[] args) {
        new Main().Test();
    }

}

返回结果:

修改前,name的值为:XiaoMing
修改后,name的值为:DaMing

解析

public static String name = "XiaoMing";

name是一个公共的 静态变量,它的初始值是XiaoMing

String variable = "name";
String value = "DaMing";

要将variable中指定的变量名的值修改为value的值。

Class clazz = Main.class;

Mainname变量所属的类,调用XXX.class可以返回一个Class反射类,但这里的Class反射类是完整的,我们可以访问其中所有的变量和方法,进行任意修改。

Field field = clazz.getDeclaredField(variable);

Class.getDeclaredField(变量名)会返回一个Field类,这个Field类可以对我们指定的变量进行读写。

field.set(clazz, value);

field.set(反射类, 值) 可以将反射类之中,符合该field变量的变量值,修改为value中指定的值。

field中存储了一个独立的变量,和Class没有关联。
只要任意类中含有和这个field中相同的变量,我们就可以直接使用field.set(反射类, 值)对其进行修改。

实战

实战演练

题目

屏幕快照 2019-10-15 下午11.15.55.png

我们要在Main类中修改在Variable类中的name变量。

打开你的IDE,试一试吧。

答案

屏幕快照 2019-10-15 下午11.18.20.png

如转载请在文章尾部添加

原作者来自 adlered 个人技术博客:https://www.stackoverflow.wiki/

评论

  1. 大佬,你的缩略图裂了

  2. 写得真好

  3. #1606453434729

    歪瑞古德

  4. 基于 Solo,我们自己改写的 bolo 菠萝博客系统,欢迎体验~

  5. 大佬,你博客的评论系统是怎么搞的?挺好用的

  6. 大佬

  7. 👍

  8. huaji 666

  9. 这里不是Bug,考虑到迁移的可用性,没有单独设立字段 😄

  10. 大佬,我用你的bolo本地搭建了博客试了一下,发现初始化的时候,管理员密码跑到b3key字段去了,是不是一个bug,还是我的姿势不对,因为可以登录,但是字段不对应

  11. 加油~你是最胖的 doge

  12. 你太帅了 doge

  13. 评论

  14. 我枯了

  15. doge 没有学会

取消