Javaの列挙型クラスの動的更新

非現実的な仕事は今、後で記録するために使用することを学ぶのは簡単容易ではありません変更手動で動的に更新列挙クラス値の必要性を満たします

1.エンジニアリングutilsパッケージのツールを持っている動的更新列挙クラスを追加します(あまりにも自分のプロジェクトに応じて、指定された場所に呼び出すことができます)

2.あなたがオンラインの例は、2つのパラメータを利用できるので、クラス、addEnumとmakeEnumメソッドを列挙して、自分に基づいて修正したい誤解に陥るようになりました

そして、私は5だった、と(自分の愚かなハローによる)、長い時間を得ることが配列であることを認識し、ああ。

パッケージcom.genju.ziji.dexiangmu.util。

輸入sun.reflect.ConstructorAccessor。
輸入sun.reflect.FieldAccessor。
輸入sun.reflect.ReflectionFactory。

輸入java.lang.reflect.AccessibleObject。
輸入java.lang.reflect.Array。
インポートをjava.lang.reflect.Field;
輸入java.lang.reflect.Modifier。
輸入はjava.util.ArrayList;
輸入java.util.Arrays。
輸入はjava.util.List;

/ **
*ダイナミックな新しい列挙ツール
* /
publicクラスDynamicEnumUtil {
プライベート静的ReflectionFactory reflectionFactory ReflectionFactory.getReflectionFactory =();

プライベート静的ボイドsetFailsafeFieldValue(フィールドフィールド、オブジェクト対象オブジェクト値)は持たないNoSuchFieldException、スロー
IllegalAccessExceptionがを{

//者がフィールドにアクセスしてみましょう
field.setAccessible(真の);

//次の我々はするフィールドのインスタンスに修飾子を変更する
ためにリフレクションをだまし、もはや最終的なものではない//
//は、私たちが静的最終フィールド変更させる
フィールドmodifiersField = Field.class.getDeclaredField(「修飾子」)。
modifiersField.setAccessible(真の);
int型修飾子= modifiersField.getInt(フィールド);

//空白アウト修飾子の最終ビットint型
修飾子を&=〜Modifier.FINAL。
modifiersField.setInt(フィールド、修飾子)。

FieldAccessor FA = reflectionFactory.newFieldAccessor(フィールド、偽);
fa.set(目標値)。
}

blankField(<?>クラスenumClass、文字列フィールド名)がないNoSuchFieldExceptionをスロープライベートの静的な無効、
IllegalAccessExceptionが{
のために(フィールドのフィールド:Class.class.getDeclaredFields()){
場合(field.getName()(フィールド名)が含まれています。){
AccessibleObject.setAccessible (新しいフィールド[] {}フィールド、TRUE)。
setFailsafeFieldValue(フィールド、enumClass、NULL);
ブレーク;
}
}
}

プライベートの静的な無効cleanEnumCache(<?>クラスenumClass)ないNoSuchFieldException、IllegalAccessExceptionが{スロー
blankField(enumClass、 "enumConstantDirectoryを"); //日(?!?Oracleの)JDK 1.5 / 6
blankField(enumClass、 "enumConstants"); // IBM JDK
}

プライベート静的ConstructorAccessor getConstructorAccessor(<?> <?>クラスenumClass、クラス[] additionalParameterTypes)が
スローないNoSuchMethodException {
クラス[] parameterTypesパラメータ=新しいクラス[additionalParameterTypes.length + 2] <?>。
parameterTypesパラメータ[0] = String.class。
parameterTypesパラメータ[1] = int.classを。
System.arraycopyの(additionalParameterTypes、0、parameterTypesパラメータ、2、additionalParameterTypes.length)。
()enumClass.getDeclaredConstructor(たparameterTypes)reflectionFactory.newConstructorAccessorを返します。
}

プライベート静的オブジェクトmakeEnumは(<?> <?>クラスenumClass、文字列値、INT序、クラス[] additionalTypes、
[] additionalValuesオブジェクト)例外{スロー
オブジェクト[] PARMSは=新しいオブジェクト[additionalValues.length + 2]。
PARMS [0] =値。
PARMS [1] = Integer.valueOf(序)。
System.arraycopyの(additionalValues、0、PARMS、2、additionalValues.length)。
enumClass.cast(getConstructorAccessor(enumClass、additionalTypes).newInstance(PARMS))を返します。
}

/ **
*判断枚举是否已存在
*
* @param値
* @param enumName
* @param <T>
* @return
* /
パブリック静的<Tがenum <?>>ブールが含まれています(リスト<T>の値を拡張して、文字列enumName){
ため(T値:値){
(value.name(IF)に等しい(enumNameは)){
trueを返します。
}
}
falseを返します。
}


/ **
*引数として与えられた列挙クラスに列挙インスタンスを追加
*
列挙の* @param <T>型(暗黙)
列挙型のクラスを変更する* @param enumType
* @paramはの名前をenumName新しい列挙型のインスタンスは、クラスに追加されます。
* /
@SuppressWarnings( "未チェック")
パブリック静的<T延び列挙<?>>空隙addEnum(クラス<T> enumType、文字列enumName、クラス<?> [] additionalTypes、[] additionalValuesオブジェクト){

// 0正気チェック
(Enum.class.isAssignableFrom(enumType)!)であれば、{
( "クラス" + enumType + "は、列挙型のインスタンスではありません")新しいのRuntimeExceptionを投げます。
}

// 1.検索「$ VALUES」ホルダー列挙クラスで、前の列挙型インスタンスを取得
フィールドvaluesField = NULLを。
フィールド[]フィールド= enumType.getDeclaredFields()。
以下のために(フィールドのフィールド:フィールド){
場合{(。field.getName()( "$ VALUES")が含まれ)
valuesField =フィールドを。
ブレーク;
}
}
AccessibleObject.setAccessible(新しいフィールド[] {} valuesField、TRUE)。

{試します

// 2.それをコピー
T [] previousValues =(T [])valuesField.get(enumType)。
リスト<T>値=新しいのArrayList <T>(は、Arrays.asList(previousValues))。

// 3.ビルド新しい列挙型
T newValueに=(T)makeEnum(enumType、enumName、values.size()、additionalTypes、additionalValues)。

IF(含有(値、enumName)){
するSystem.out.println( "列挙:" + enumName + "已の存在")。
返します。
}

// 4.新しい値の追加
values.add(newValueにします)。

// 5.新しい値のフィールド
setFailsafeFieldValue(valuesField、ヌル、values.toArray((T [])Array.newInstance(enumType、0)))。

// 6.クリーン列挙キャッシュ
cleanEnumCache(enumType)。

}キャッチ(例外e){
e.printStackTrace();
新しいのRuntimeException(e.getMessage()、e)を投げます。
}
}

}

3.テスト

公共の静的な無効メイン(文字列引数[]){

  addEnum( "1"、 "2"、 "3"、 "4"、 "5")。

  用(サブバンクE:SunBank.values()){

    System.out.println(e.getBankName())。

  }

}

プライベートの静的な無効addEnum(文字列enumName、文字列ID、文字列名、文字列のDESC、AreaType areaType、リスト<クラス<?列挙>> paramTypesを拡張します){

      DynamicEnumUtil.addEnum(Subank.class、enumName、

      新しいクラス<?> [] {Stirng.class、String.class、AreaType.class、List.Class} 

      新しいオブジェクト[] {ID、NAE、DESC、areaType、paramTypes})。

  }

 

最後に、印刷の効果を調べることで追加するのに十分な大丈夫です、私はここに列挙クラスに直接記述することですので、あまりにも自分のニーズに応じて動的に行うことができる必要があります。

場所は正確に指導を歓迎していなかった場合

おすすめ

転載: www.cnblogs.com/KpGo/p/11527473.html