当前位置: 首页 > 面试题库 >

用反射设置私有静态最终字段

罗法
2023-03-14
问题内容

基于使用Java反射更改私有静态最终字段,我尝试设置私有静态最终字段。

(我知道这非常骇人,但是这个问题与代码质量无关;与Java反射有关。)

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

class Main {

  static class Foo {
    private static final int A = 1;

    int getA() {
      return A;
    }
  }

  public static void main(String[] args) throws Exception {
    Field modifiers = Field.class.getDeclaredField("modifiers");
    modifiers.setAccessible(true);

    Field field = Foo.class.getDeclaredField("A");
    field.setAccessible(true);
    modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, 2);

    System.out.println(new Foo().getA()); // should print 2
  }

}

此打印

1

我已经使用OpenJDK 6和7,以及Oracle 7进行了尝试。

我不知道Java反射可以提供什么保证。但是,如果失败了,我以为会有一个Exception(实际上所有反射方法都会抛出异常)。

这是怎么回事


问题答案:

Java内联final字段可在编译时初始化为
常量表达式


根据Java语言规范,使用在编译时可以求值的表达式初始化的任何static final*字段都必须编译为“内联”字段值的字节码。也就是说,没有动态链接将出现内部类Main,告诉它来获取值AInterfaceA在运行时。

对字节码进行反编译,您会发现getA()简单地将常量推入1并返回它。

  • -JavaWorld引用说static final。Kumar指出,语言规范在 常量变量 的定义中static不需要。我认为Kumar是正确的,而JavaWorld是错误的。 __


 类似资料:
  • 我有两个UnitTest项目为我的Android项目。一个用于JUnit测试,一个用于Android Unit测试。在JUnit测试项目中,我创建了一个类来访问或设置私有字段、方法或构造函数。(附言:对于那些对完整代码感到好奇的人,请告诉我,我会把它添加到这篇文章的底部。) 我也有UnitTets来测试这些私有方法的访问。现在,所有这些UnitTest都可以工作,接受一个:设置final stat

  • 问题内容: 我有一堂课,但不幸的是,我需要在运行时更改它。 使用反射我得到这个错误: 有什么办法可以改变价值? 问题答案: 假设没有阻止你执行此操作,则可以使用来绕开并重置修饰符以摆脱,并实际上修改字段。 这是一个例子: 假设没有SecurityException抛出,上面的代码将打印出来”Everything is true”。 实际执行的操作如下: 基本boolean值true和falsein

  • 使用Java反射更改私有静态final字段 我按照上面链接中的说明使用java反射更改私有静态final字段。我有一个名为“数据”的对象在“data”内部,有一个名为“type”的私有静态最终变量我想将“type”设置为null。这是我的密码。 我试着在Java1.7上用类似的代码来做这件事,结果成功了。但是在Android上运行此代码会产生以下错误:java。lang.NoSuchFieldEx

  • 问题内容: 我有2类:和 通过反思,我想在课堂上设置: 但我有一个例外: 线程“主”中的异常java.lang.NoSuchFieldException:a_field 但是,如果我尝试: 有用。 使用setter方法我有同样的问题: 问题答案: 要访问私有字段,您需要设置为true。您可以离开超类领域。此代码有效:

  • 这是我得到的错误(在setMOTD的最后第二行):

  • } 当我做它将打印芒果,但它仍然在打印苹果。如果有人能帮助我只使用MOCKITO而不是PowerMock等。