2017-01-03 6 views
-1

Change private static final field using Java reflectionする方法を発見しました。それ以来、リフレクトで最終フィールドを変更するために使用していますが、なぜ同じロジックを適用できないのか疑問に思っていますフィールドの型に変換します。私は、しかし、これはそれが元々ArrayListまたは他のいくつかのより高いレベルのクラスだったときに、たとえば、Objectにフィールドのタイプを設定した場合、これはアプリケーションに影響を与えるだろうか疑問に私を導いたリフレクトでフィールドの宣言された型を変更することができます

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()); 
    } 
} 

を思い付きました。 JVM内で内部エラーが発生するか、この値が単にJVMのデータのクローンであり、それを変更しても効果はありません。被験者に出すことのできる光は大変ありがたいです。

+1

短い回答:いいえ。変数のタイプを変更することはできません。また、スコープを変更することもできません(例えば静的にする)。 –

+1

JVMがサポートしている場合、インストルメンテーションでしか実行できません。主流のJVMはこれをまったくサポートしていません。 – Holger

答えて

2

あなたは、箱の中に箱に入れたものと考えることができます(箱全体がオブジェクトを表し、箱内の各ボックスがフィールドを表しています)。リフレクションではボックスの内容を変更できますが、ボックスの形状や全体の形状を変更することはできません。クラスの構造はロードされると固定されます。

.classファイルから読み取っているので、その場で変更する方法があります。このプロセスは、バイトコード製織として知られています。言うまでもなく、それはちょっと難解です(例えば、longではなくintをとるメソッドを変更した場合、longの代わりにintに渡すためにそのメソッドのすべての呼び出しサイトを変更する必要があります) 。

0

計測器は、クラスがまだロードされていない場合は、タイプを変更できます。一度クラスが読み込まれると、型の変更ははるかに難しくなります。

Unsafeを使用すると、Object参照のintをスワップしてメモリにアクセスできますが、これはすべて自己責任で行ってください。

注:実行時に参照のタイプをListからObjectに変更しても、参照される実際のオブジェクトのタイプは変更されません。

関連する問題