如何在asm访问字段方法中提取字段的访问标志

Sha*_*938 0 java bytecode java-bytecode-asm

我正在尝试使用访问者 API 通过 ASM 6 实现一些类转换。我需要知道某个字段是否具有特定的访问标志。例如,字段可以是 ACC_PUBLIC + ACC_STATIC。在visitField方法中,访问标志是9。那么我如何知道该字段是否是静态的?

谢谢

Hol*_*ger 5

除了可以使用 中定义的实用程序方法java.lang.reflect.Modifier(如 )之外,您始终可以使用按位与运算符 ( )isStatic(access)来测试位的存在:&

\n\n
@Override\npublic MethodVisitor visitMethod(int access, String name, String desc,\n                                 String signature, String[] exceptions) {\n    // for a single flag bit, test against zero is sufficient\n    boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;\n    // otherwise, compare with the combination itself\n    final int PUBLICSTATIC = Opcodes.ACC_STATIC|Opcodes.ACC_PUBLIC;\n    boolean isPublicAndStatic = (access & PUBLICSTATIC) == PUBLICSTATIC;\n    // likewise, you can test for the absence of bits:\n    final int ACCESS_LEVEL = Opcodes.ACC_PUBLIC|Opcodes.ACC_PROTECTED|Opcodes.ACC_PRIVATE;\n    boolean isPackagePrivate = (access & ACCESS_LEVEL) == 0;\n    // this allows testing for things not provided by java.lang.reflect.Modifier\n    boolean isVarArgs = (access & Opcodes.ACC_VARARGS) != 0;\n\n    \xe2\x80\xa6\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果你想提取和解码所有位,你可以使用 中的实用方法java.lang.Integer,例如:

\n\n
StringJoiner j = new StringJoiner(" ").setEmptyValue("(package-private)");\nfor(int remaining = access, bit; remaining != 0; remaining -= bit) {\n    bit = Integer.lowestOneBit(remaining);\n    switch(bit)\n    {\n        case Opcodes.ACC_PUBLIC:       j.add("public"); break;\n        case Opcodes.ACC_PRIVATE:      j.add("private"); break;\n        case Opcodes.ACC_PROTECTED:    j.add("protected"); break;\n        case Opcodes.ACC_STATIC:       j.add("static"); break;\n        case Opcodes.ACC_FINAL:        j.add("final"); break;\n        case Opcodes.ACC_SYNCHRONIZED: j.add("synchronzied"); break;\n        case Opcodes.ACC_BRIDGE:       j.add("(bridge)"); break;\n        case Opcodes.ACC_VARARGS:      j.add("(varargs)"); break;\n        case Opcodes.ACC_NATIVE:       j.add("native"); break;\n        case Opcodes.ACC_ABSTRACT:     j.add("abstract"); break;\n        case Opcodes.ACC_STRICT:       j.add("strictfp"); break;\n        case Opcodes.ACC_SYNTHETIC:    j.add("synthetic"); break;\n    }\n}\nString decoded = j.toString();\n
Run Code Online (Sandbox Code Playgroud)\n