多くのバイトコードエンジニアリングライブラリを使用して.classを変更できます。たとえば、javaassistを使用します。
ただし、静的なfinalメンバーを置き換えようとしている場合は、コンパイラーがこの定数を使用する場所にインライン化するため、目的の効果が得られない可能性があります。
javaassist.jarを使用したサンプルコード
//ConstantHolder.java
public class ConstantHolder {
public static final String HELLO="hello";
public static void main(String[] args) {
System.out.println("Value:" + ConstantHolder.HELLO);
}
}
//ModifyConstant.java
import java.io.IOException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.NotFoundException;
//ModifyConstant.java
public class ModifyConstant {
public static void main(String[] args) {
modifyConstant();
}
private static void modifyConstant() {
ClassPool pool = ClassPool.getDefault();
try {
CtClass pt = pool.get("ConstantHolder");
CtField field = pt.getField("HELLO");
pt.removeField(field);
CtField newField = CtField.make("public static final String HELLO=\"hell\";", pt);
pt.addField(newField);
pt.writeFile();
} catch (NotFoundException e) {
e.printStackTrace();System.exit(-1);
} catch (CannotCompileException e) {
e.printStackTrace();System.exit(-1);
} catch (IOException e) {
e.printStackTrace();System.exit(-1);
}
}
}
この場合、プログラムはHELLOの値を「Hello」から「Hell」に正常に変更します。ただし、ConstantHolderクラスを実行すると、コンパイラによるインライン化のため、「Value:Hello」が出力されます。
それが役に立てば幸い。