Shin938
Shin938

Reputation: 969

how to extract access flags of a field in asm visitField method

I'm trying to implement some class transformation with ASM 6 using the visitor API. I need to know if a field has a certain access flag. for example a field could be ACC_PUBLIC + ACC_STATIC. in the visitField method the access flag is 9. so how can i know if the field is static?

Thanks

Upvotes: 0

Views: 1401

Answers (2)

Holger
Holger

Reputation: 298153

Besides the possibility to use utility methods defined in java.lang.reflect.Modifier, like isStatic(access), you can always test the presence of a bit using the bitwise and operator (&):

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

    …
}

If you want to extract and decode all bits, you can use utility methods in java.lang.Integer, e.g.:

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

Upvotes: 5

Shin938
Shin938

Reputation: 969

I found the answer in class java.lang.reflect.Modifier that has static method to query access modifiers for example isStatic(access).

Upvotes: 0

Related Questions