当前位置: 首页 > 知识库问答 >
问题:

在Java 17中覆盖final字段

宋健柏
2023-03-14

我试图通过反射在Java17覆盖非静态最终字段的值。

据我所知,从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的新版本,是否有等效的方法覆盖最终字段?在谷歌中的快速搜索没有产生与上述解决方案不同的任何结果。我唯一学到的是,覆盖静态最终字段是不可能的,而通过反射仍然可以覆盖非静态最终字段,但我找不到方法。

共有1个答案

经博延
2023-03-14

这应该可行:

 Field field = foo.getClass().getDeclaredField("bar");
        field.setAccessible(true);
        field.set(foo, "changedBar");
 类似资料:
  • 据我所知,<code>override</code>关键字声明给定的声明实现了一个基本<code>virtual</code>方法,如果没有找到匹配的基本方法,编译应该失败。 我对< code>final关键字的理解是,它告诉编译器任何类都不能覆盖这个< code >虚拟函数。 那么是多余的吗?它似乎编译得很好。最终传达哪些信息而信息不传达?这种组合的用例是什么?

  • 在这个特定的示例中,我扩展了

  • 我有一个pdf模板,我试图在新文档中重写它。我需要从模板PDF中获取一些字段,并在新的PDF中重写它们的值。我这样做: 但我发现了一个例外: iText。内核PDFEException:“没有用于生成间接项的关联PdfWriter。” 我做错了什么以及如何修复它?这是第七次。

  • 问题内容: 是否可以强制重命名os.rename覆盖另一个文件(如果已经存在)?例如,在下面的代码中,如果文件Tests.csv已经存在,则将其替换为Tests.txt文件(该文件也已重命名为Tests.csv)。 问题答案: 您可以尝试: 或然后:

  • 问题内容: 我想更改admin django中的某些CSS,例如base.css。直接在Django库中进行更改是否更好?如何以最佳方式覆盖它? 问题答案: 这取决于你要做什么。虽然首先:不要直接在Django管理员中覆盖它。我认为你有两种选择是合理的: 通常,如果要更改管理员的外观,则应覆盖管理模板。此处详细介绍:覆盖管理模板。有时候,你可以扩展原始管理文件,然后覆盖块就像作为一个例子。 如果你

  • 问题内容: 我有一个抽象类,应该实现一个公共字段,该字段是一个接口或另一个抽象类。 像这样的东西: 现在我有另一个专门的类容器: Java的让我编译这个,和我想象的领域中被自动重载领域的......这些问题是:我是对这个?孩子的自动“超载”会发生吗? 而且,更重要的问题是,如果我还有另一个这样的课: 会返回1还是2?我的意思是容器字段将称为通用字段还是特殊字段?还有,如果特殊的prop1被声明为S