通过反射改变最终变量,为什么静态和非静态最终变量之间存在差异

验证

请参考下面的代码。运行代码时,我可以更改最终的非静态变量的值。但是,如果我尝试更改最终静态变量的值,则会抛出异常java.lang.IllegalAccessException

我的问题是,为什么在非静态最终变量也不会抛出异常,反之亦然。为什么会有所不同?

import java.lang.reflect.Field;
import java.util.Random;

public class FinalReflection {

    final static int stmark =  computeRandom();
    final int inmark = computeRandom();

    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        FinalReflection obj = new FinalReflection();
        System.out.println(FinalReflection.stmark);
        System.out.println(obj.inmark);
        Field staticFinalField  = FinalReflection.class.getDeclaredField("stmark");
        Field instanceFinalField  = FinalReflection.class.getDeclaredField("inmark");
        staticFinalField.setAccessible(true);
        instanceFinalField.setAccessible(true);

        instanceFinalField.set(obj, 100);
        System.out.println(obj.inmark);

        staticFinalField.set(FinalReflection.class, 101);
        System.out.println(FinalReflection.stmark);

    }

    private static int computeRandom() {
        return new Random().nextInt(5);
    }
}
纳伦德拉·帕塔伊(Narendra Pathai)
FinalReflectionobj = new FinalReflection();
System.out.println(FinalReflection.stmark);
System.out.println(obj.inmark);
Field staticFinalField  = FinalReflection.class.getDeclaredField("stmark");
Field instanceFinalField  = FinalReflection.class.getDeclaredField("inmark");
staticFinalField.setAccessible(true);
instanceFinalField.setAccessible(true);

//EXTRA CODE
//Modify the final using reflection
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(staticFinalField, staticFinalField.getModifiers() & ~Modifier.FINAL);


instanceFinalField.set(obj, 100);
System.out.println(obj.inmark);
staticFinalField.set(FinalReflection.class, 101);
System.out.println(FinalReflection.stmark);

此解决方案并非没有缺点,它可能无法在所有情况下都有效:

如果final在字段声明中将字段初始化为编译时常量,则对该字段的更改final可能不可见,因为最终字段的使用会在编译时用编译时常量替换。

另一个问题是,该规范允许对final字段进行积极的优化在线程内,可以final使用final在构造函数中不进行的对字段的那些修改来重新排序对字段的读取更多关于这也是在这个类似的问题解释。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

最终变量和非最终变量之间的快速差异 最终让与非最终让

来自分类Java

使用反射访问静态最终变量

来自分类Java

为什么默认情况下接口变量是静态变量和最终变量?

来自分类Java

最佳实践:Java静态非最终变量

来自分类Dev

为什么局部类会接受静态最终变量?

来自分类Java

Java中静态和非静态最终原始字段之间的性能差异

来自分类Java

Java中的静态最终变量

来自分类Java

为什么在静态初始化块中不允许使用合格的静态最终变量?

来自分类Java

为什么当我们调用静态最终变量时不首先执行静态块

来自分类Dev

为什么静态最终变量使用静态方法初始化需要同步?

来自分类Java

静态和最终之间的区别?

来自分类Java

通过对象访问时,静态最终字段和实例最终字段之间的差异在声明时初始化

来自分类Java

行为差异:“ null”初始化的最终静态成员和“ null”初始化的最终局部变量

来自分类Java

Java中“私有静态最终”和“公共静态最终”类变量的最接近Ruby表示?

来自分类Java

正则表达式查找静态(非最终)变量

来自分类Dev

注释中静态最终变量的目的是什么?

来自分类Dev

为什么不能在实例块中为最终的静态变量分配值?

来自分类Java

为什么一个变量需要在最终块静态

来自分类Java

为什么单例线程安全的此静态最终变量安全?

来自分类Dev

为什么我不能在psvm Java中创建静态最终变量?

来自分类Java

Java中静态变量与最终静态变量之间的区别

来自分类Java

最终静态和静态最终之间的区别

来自分类Java

枚举内的私有静态最终变量

来自分类Dev

声明私有静态最终变量的原因

来自分类Java

静态最终变量的Java命名约定

来自分类Java

使用属性文件而不是静态最终变量

来自分类Java

Java枚举静态最终实例变量

来自分类Dev

在方法中声明的最终静态布尔变量

来自分类Dev

静态最终变量和静态初始化程序块

Related 相关文章

  1. 1

    最终变量和非最终变量之间的快速差异 最终让与非最终让

  2. 2

    使用反射访问静态最终变量

  3. 3

    为什么默认情况下接口变量是静态变量和最终变量?

  4. 4

    最佳实践:Java静态非最终变量

  5. 5

    为什么局部类会接受静态最终变量?

  6. 6

    Java中静态和非静态最终原始字段之间的性能差异

  7. 7

    Java中的静态最终变量

  8. 8

    为什么在静态初始化块中不允许使用合格的静态最终变量?

  9. 9

    为什么当我们调用静态最终变量时不首先执行静态块

  10. 10

    为什么静态最终变量使用静态方法初始化需要同步?

  11. 11

    静态和最终之间的区别?

  12. 12

    通过对象访问时,静态最终字段和实例最终字段之间的差异在声明时初始化

  13. 13

    行为差异:“ null”初始化的最终静态成员和“ null”初始化的最终局部变量

  14. 14

    Java中“私有静态最终”和“公共静态最终”类变量的最接近Ruby表示?

  15. 15

    正则表达式查找静态(非最终)变量

  16. 16

    注释中静态最终变量的目的是什么?

  17. 17

    为什么不能在实例块中为最终的静态变量分配值?

  18. 18

    为什么一个变量需要在最终块静态

  19. 19

    为什么单例线程安全的此静态最终变量安全?

  20. 20

    为什么我不能在psvm Java中创建静态最终变量?

  21. 21

    Java中静态变量与最终静态变量之间的区别

  22. 22

    最终静态和静态最终之间的区别

  23. 23

    枚举内的私有静态最终变量

  24. 24

    声明私有静态最终变量的原因

  25. 25

    静态最终变量的Java命名约定

  26. 26

    使用属性文件而不是静态最终变量

  27. 27

    Java枚举静态最终实例变量

  28. 28

    在方法中声明的最终静态布尔变量

  29. 29

    静态最终变量和静态初始化程序块

热门标签

归档