《三分钟包会》Java 初学指♂男:“说说初学的误区与死结”( 壹 | 反射与 Field )

贼拉正经的技术博客 A 本文由博客端 https://106.13.71.6/blog 主动推送
本贴最后更新于 262 天前,其中的信息可能已经时移世异

🕐 莫要着急往下翻,倒计时闹钟正在加载中...

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

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

⏰ 三分钟过去了,你学会了吗?

赞助商 我要投放

15 回帖
请输入回帖内容 ...
  • csfwff 1

    doge 没有学会

    1 回复
  • adlered

    我枯了

  • geektomya 1

    太顶了!

  • Lee981265 1

    我要好好学一学 😄

  • someone

    bbcc

  • 614756773

    教练,我不仅想修改 变量值,我还想修改 变量名
    教练我想学这个!

    1 回复
  • adlered 1 2 评论

    哈哈哈哈哈,这个简单

    String a = "hello";
    String b = a;
    a = null;
    

    JVM 会自动回收 a,搞定

    思路清晰明了,不过为啥让我想到了睡眠排序(滑稽)
    614756773
    @614756773 哈哈哈,可能是因为太简单粗暴了吧
    adlered
  • buwangchuxin 1 评论

    这道题太难了,我不会!!!trollface

    大佬谦虚了~我瞎写的
    adlered
  • someone 1

    加油~你是最胖的 doge

  • someone 1

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

  • someone 1

    huaji 666

    1 回复
  • adlered

    别啊哥

    1 回复
  • JssDream 1

    挺好的啊,加油doge

  • btlinux

    点赞投币收藏了trollface

    1 回复
  • adlered

    谢谢老铁三连

请输入回帖内容 ...