javassist字段检查初始化

时间:2013-03-20 18:14:57

标签: java reflection initialization field javassist

我目前正在实施一个Annotation,强制字段通过javassist来尊重条件。我想检查一个字段在被读取时是否被初始化...所以,目前,当我们通过Translator.onLoad(ClassPool pool, String className)加载它们并使用{{{}时加载它们时,我会通过加载它来获取它们。 1}}通过覆盖ExprEditor方法在每个类上。现在,我设法通过在edit(FieldAccess arg)

中运行以下方法来注入代码来检查条件
onLoad

您是否可以指出我是否找到了某个字段已初始化的正确方向?请注意,字段可以是原始字段。

提前致谢。

1 个答案:

答案 0 :(得分:1)

假设

我将假设以下内容:

  • 通过字段初始化,我们讨论为空的字段。

  • 原始类型不能为空,因此无需检查它们。

代码

此示例验证适用于静态和非静态字段。

我还在几行中创建了代码String,以提高可读性。作为 arg FieldAccess 对象,您可以编写以下内容:

 if (arg.isReader() && !arg.getField().getType().isPrimitive()) {
  String code = "{ java.lang.Object var = $proceed();"
               +  "if(var == null) {"
                   + "java.lang.System.out.println(\"not initialized " + arg.getFieldName() + "\");"
               +  "}"
               + "$_=var;}";
            arg.replace(code);
        }

代码说明

正如您所看到的,在这个小例子中我使用了一些javassist标识符,有关此内容的完整参考,请阅读javassist official tutorial(我链接到有关代码修改的部分)。

以下是每个标识符的含义:

  • $ proceed():如果是字段访问,则返回字段的值。
  • $ _ :这是在读取模式下编辑FieldAccess时必需的标识符。此标记包含将用于设置字段的值。

有了这些信息,很容易理解代码的想法:

  1. 将字段值放入名为 var
  2. 的辅助对象中
  3. 检查字段是否为空,如果是,则打印带字段名称的警告
  4. 使用值设置字段名(无论是否为空);
  5. 我想这已经指出了正确的方向。但是,如果您还有其他需要,请告诉我。