所以我发现了Change private static final field using Java reflection一段时间以来一直使用它来修改带有反射的最终字段,然后我想知道为什么我不能将相同的逻辑应用于类型领域。我想出了
public static void changeFieldType(Field field, Class newType){
try {
Field typeField = Field.class.getDeclaredField("type");
typeField.setAccessible(true);
typeField.set(field, newType);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
LogUtil.printErr("Failed to edit field type for " + field.getName());
}
}
然而,这让我想知道如果你将一个字段的类型设置为Object
,当它最初是ArrayList
或其他更高级别的类时,这将如何影响应用程序。这会在JVM中创建内部错误,还是仅仅是JVM数据的克隆并且更改它不会产生任何影响。你可以对这个主题有所了解。非常感谢。
答案 0 :(得分:3)
您可以将值视为放入箱子中的框中的内容(表示整个对象的箱子,其中的每个框表示一个字段)。反射允许您更改框的内容,但它不允许您更改任何框的形状,也不允许更改框的整体形状。该类的结构在加载后即被修复。
但是,有一些方法可以随时更改它,因为它是从.class
文件中读取的。该过程称为字节码编织。不用说,它有点棘手(例如,如果你改变一个方法来取一个int而不是一个long,那么你还需要改变该方法的所有调用站点以传入int而不是long)
答案 1 :(得分:0)
如果班级尚未加载,则仪器可以更改类型。一旦加载了类,更改类型就会困难得多。
使用“不安全”,您可以根据需要访问内存,将int
替换为Object
引用,但这完全由您自行承担风险。
注意:在运行时将引用类型从List
更改为Object
将不会更改引用的实际对象的类型。