2017-01-03 78 views
-1

所以我發現如何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數據的一個副本,並且改變它不會起作用。任何你可以解決這個問題的光是非常感謝。

+1

簡答:不。無法更改變量的類型,也無法更改其範圍(例如,使其變爲靜態)。 –

+1

只有JVM支持,Instrumentation才能執行此操作。主流JVM根本不支持這一點。 – Holger

回答

2

您可以將值放在箱子內的框中(表示整個對象的箱子以及表示一個域的每個箱子)。反射可讓您更改框的內容,但它不會讓您更改任何框的形狀,也不會更改框的整體形狀。該類的結構在加載後會被修復。

儘管如此,在從.class文件中讀取文件時,仍可以隨時對其進行更改。該過程稱爲字節碼編織。不用說,這有點麻煩(例如,如果你改變一個方法來接受一個int而不是一個long,那麼你也需要改變該方法的所有調用位置以傳入一個int而不是一個long) 。

0

如果班級尚未加載,儀表可以更改類型。一旦加載了一個類,改變類型就困難得多。

使用不安全,您可以隨意訪問內存,交換intObject參考,但這完全是在使用您自己的風險。

注意:在運行時將參考的類型從List更改爲Object不會更改引用的實際對象的類型。