私は現在、フィールドが javassist を介して条件を尊重するように強制するアノテーションを実装しています。フィールドが読み取られているときにフィールドが初期化されているかどうかを確認したい...そのため、現在、 を介してVMによってロードされたときにクラスをロードし、メソッドをオーバーライドして各クラスTranslator.onLoad(ClassPool pool, String className)
で を使用してクラスを取得しています. 現時点では、内部で次のメソッドを実行することにより、コードを挿入して状態を確認することができました。ExprEditor
edit(FieldAccess arg)
onLoad
private void processFields(FieldsAndMethods data) {
final FieldsAndMethods copy = data;
Stack<CtClass> classes = data.getThisClass();
for(CtClass cc : classes ){
try {
cc.instrument(new ExprEditor(){
@Override
public void edit(FieldAccess arg) throws CannotCompileException{
try{
CtField field = arg.getField();
if(copy.getFields().contains(field) &&
field.hasAnnotation(Assertion.class)){
Assertion a =
((Assertion)field.getAnnotation(Assertion.class))
String condition = assertion.value();
String fieldName = field.getName();
String processCondition =
transformCondition(condition, fieldName);
if(arg.isWriter()){
String code = "{if(" + evaledCondition + ")" +
"$proceed($$) ;" +
"else throw new " +
"RuntimeException(\"The assertion " +
condition + " is false.\");}";
arg.replace(code);
}else if (arg.isReader()){
//Here is where I would like to check if the field
//has been initialized...
}
}catch(ClassNotFoundException e){
System.out.println("could not find Annotation " +
Assertion.class.getName() );
}catch(NotFoundException e){
System.out.println("could not find field " +
arg.getFieldName() );
}
}
});
} catch (CannotCompileException e) {
System.out.println("Could not interpret the expression");
System.out.println(e);
}
}
}
private String transformCondition(String condition, String fieldName){
return condition.replace(fieldName, "$1");
}
フィールドが初期化されているかどうかを確認するための正しい方向を教えていただけますか? フィールドはプリミティブであってもなくてもよいことに注意してください。
前もって感謝します。