在 Java 17 中覆盖 Final 字段

问题描述 投票:0回答:2

我正在尝试通过 Java 17 中的反射覆盖非静态最终字段的值。

据我所知,从 Java 12 及以上版本开始,你不能再执行以下技巧:

import java.lang.reflect.*;

class Foo {
private final String bar;

    public Foo(String bar) {
        this.bar = bar;
    }
    
    public String getBar() {
        return this.bar;
    }

}

public class Example {

    public static void main(String[] args) {
        Foo foo = new Foo("foobar");
        System.out.println(foo.getBar());
    
        try {
            Field field = foo.getClass().getDeclaredField("bar");
            field.setAccessible(true);
            Field modifiers = field.getClass().getDeclaredField("modifiers");
            modifiers.setAccessible(true);
            modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        } catch (Exception e) {
            e.printStackTrace();    
        }
    
        System.out.println(foo.getBar());
    }

}

当我在 Java 17 中运行它时,抛出以下异常:

foobar java.lang.NoSuchFieldException: modifiers    at java.base/java.lang.Class.getDeclaredField(Class.java:2610)  at Example.main(Example.java:24) foobar

“bar”的值保持不变。

对于较新版本的 Java 是否有覆盖 Final 字段的等效方法?在谷歌中快速搜索并没有产生与上述解决方案不同的任何结果。我唯一了解到的是,不可能覆盖静态最终字段,而仍然可以通过反射覆盖非静态最终字段,但我不知道如何实现。

java reflection
2个回答
0
投票

也许已经晚了,但我找到了解决方案这里。 Java17修饰符

您需要添加 JVM 启动选项:

--add-opens=java.base/java.lang.reflect=ALL-UNNAMED 
--add-opens=java.base/java.net=ALL-UNNAMED

Java代码:

        VarHandle MODIFIERS;
        var lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
        MODIFIERS = lookup.findVarHandle(Field.class, "modifiers", int.class);
        MODIFIERS.set(field, field.getModifiers() & ~Modifier.FINAL);

-2
投票

这应该有效:

 Field field = foo.getClass().getDeclaredField("bar");
 field.setAccessible(true);
 field.set(foo, "changedBar");
© www.soinside.com 2019 - 2024. All rights reserved.