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

修改Java中的最终字段

李成礼
2023-03-14
问题内容

让我们从一个简单的测试用例开始:

import java.lang.reflect.Field;

public class Test {
  private final int primitiveInt = 42;
  private final Integer wrappedInt = 42;
  private final String stringValue = "42";

  public int getPrimitiveInt()   { return this.primitiveInt; }
  public int getWrappedInt()     { return this.wrappedInt; }
  public String getStringValue() { return this.stringValue; }

  public void changeField(String name, Object value) throws IllegalAccessException, NoSuchFieldException {
    Field field = Test.class.getDeclaredField(name);
    field.setAccessible(true);
    field.set(this, value);
    System.out.println("reflection: " + name + " = " + field.get(this));
  }

  public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
    Test test = new Test();

    test.changeField("primitiveInt", 84);
    System.out.println("direct: primitiveInt = " + test.getPrimitiveInt());

    test.changeField("wrappedInt", 84);
    System.out.println("direct: wrappedInt = " + test.getWrappedInt());

    test.changeField("stringValue", "84");
    System.out.println("direct: stringValue = " + test.getStringValue());
  }
}

任何人都在乎猜测什么将作为输出打印(在底部显示,以免立即破坏惊喜)。

问题是:

  1. 为什么原始和包装的整数表现不同?
  2. 为什么反射访问与直接访问返回不同的结果?
  3. 最困扰我的人-为什么String表现得像原始的int而不是像Integer

结果(java 1.5):

reflection: primitiveInt = 84
direct: primitiveInt = 42
reflection: wrappedInt = 84
direct: wrappedInt = 84
reflection: stringValue = 84
direct: stringValue = 42

问题答案:

内联编译时常量(在javac编译时)。参见JLS,尤其是15.28定义了常量表达式,而13.4.9讨论了二进制兼容性或最终字段和常量。

如果使字段为非最终值或分配非编译时间常量,则不会内联该值。例如:

private final String stringValue = null!= null?“”:“ 42”;



 类似资料:
  • 如果您构建了一个对象,说“intruder”并将其定义为final,那么您仍然可以更改类定义中不是final的对象字段(即intruder.power=50;)。在这种情况下,限制将是关于入侵者的对象引用,而不是内部值。 我的问题是:字符串作为一个例子呢?如果您创建了一个字符串对象,比如“String s=new String(”str“);是否有一种方法可以更改字符串的”str“值?如果没有,为

  • 我有一个String,newNumber=106,nn=3和差异=3。 输出: 我想修改这个字符串,使输出变成,然后用这个新字符串我想再次修改它,使它变成,基本上我只需要替换新的数字,它是106,并且一直变为11,正如你所看到的,我试图只修改newNumber并用另一个替换它,同时保持整个字符串不变,我只是替换并添加它,这是如何实现的?输出应该是这样的,输出: 我在用步骤求解一个方程,公式无关紧要

  • 我需要在我的应用程序中创建100个或更多的静态最终常数,我可以通过以下两种方式实现这一点: 创建一个简单的java并在该类中创建字段 创建接口时应将所有变量放入其中,因为接口中的所有字段都是隐式的 在上述方法中,我有以下问题: 哪种方法是实现这一目标的正确方法

  • 问题内容: 为对象 声明关键字有什么用?例如: 问题答案: 使用“ final”关键字可使您声明的变量不变。最初分配后,将无法重新分配。 但是,这不一定意味着变量引用的实例状态是不可变的,仅引用本身是不可变的。 在变量上使用“ final”关键字有几个原因。一种是优化,通过将变量声明为final来允许值被记忆。 使用最终变量的另一种情况是方法中的内部类需要访问声明方法中的变量。以下代码说明了这一点

  • 问题内容: 关键字如何使变量不可变?维基百科说没有。 问题答案: 在Java中,术语 final 是指引用,而不 可变 是指对象。将修饰符分配给引用意味着它不能更改为指向另一个对象,但是如果对象是可变的,则可以对其进行修改。 例如: 就像Wikipedia文章中提到的那样,如果您来自C ++,则必须分离出into 和不可变的概念。

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