【发布时间】:2013-03-20 18:14:56
【问题描述】:
我目前正在实现一个注释,它强制字段通过 javassist 遵守条件。我想检查一个字段在被读取时是否被初始化......所以,目前,我通过在VM通过Translator.onLoad(ClassPool pool, String className)加载它们时加载它们来获取类,并使用ExprEditor on每个类通过覆盖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");
}
您能否指出正确的方向来确定字段是否已初始化?请注意,字段可以是原始字段,也可以不是原始字段。
提前致谢。
【问题讨论】:
-
您的意思是要注入代码以检查字段是否已初始化,还是要检查字段是否在转换过程中已初始化?
-
由于字段受断言约束,我必须检查它们是否尚未初始化(默认值可能会破坏条件)。每个字段都访问一个未初始化的变量(当然,构造函数或初始化程序中的任何初始化除外)。
标签: java reflection initialization field javassist