在 Java 中,final 关键字用于声明一个常量,一旦被赋值后就不能被修改。因此,反射无法直接修改 final 属性的值。\n\n然而,可以借助反射机制来绕过 final 关键字的限制,虽然这样做并不被推荐,因为它破坏了 final 属性的不可变性。下面是一个修改 final 属性值的示例代码:\n\njava\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\n\npublic class Main {\n public static void main(String[] args) throws Exception {\n MyClass obj = new MyClass();\n System.out.println("Before modification: " + obj.getTent());\n\n Field field = obj.getClass().getDeclaredField("tent");\n field.setAccessible(true);\n \n // 修改final字段前,将其修饰符设置为可修改\n Field modifiersField = Field.class.getDeclaredField("modifiers");\n modifiersField.setAccessible(true);\n modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);\n\n // 修改final字段的值\n field.set(obj, 456);\n\n System.out.println("After modification: " + obj.getTent());\n }\n}\n\nclass MyClass {\n private final int tent = 123;\n\n public int getTent() {\n return tent;\n }\n}\n\n\n在上述示例中,通过使用反射获取tent字段,并将其修饰符设置为非final,然后通过field.set(obj, 456)将其值修改为456。最后输出修改后的值。\n\n需要注意的是,这种修改 final 属性的方式是不安全的,因为它违反了 final 属性的设计意图。在实际开发中,应该尽量避免使用反射修改 final 属性的值。\n\n与使用new关键字创建对象不同,反射机制允许在运行时动态地获取和修改类的属性、方法和构造函数等信息。使用new关键字创建对象是在编译时确定的,而反射可以在运行时根据需要获取和操作类的成员。

Java 反射修改 final 属性:原理、示例与风险 - 与 new 的区别

原文地址: https://www.cveoy.top/t/topic/qxbP 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录