I found interesting thing while working with reflection. I tried to retrieve constructors of simple class and their modifiers.
public class Test {
public Test(Object... args) {}
}
Here is the code to retrieve constructor modifiers:
Class<?> clazz = Test.class;
Constructor<?>[] ctors = clazz.getDeclaredConstructors();
for (Constructor<?> ctor : ctors) {
int mod = ctor.getModifiers();
/*if not package-private modifier*/
if(mod!=0) {
System.out.println( Modifier.toString(mod)));
}
}
The result is:
public transient
If I pass to constructor not variable parameters, but just array, it’s ok.
public class Test {
public Test(Object[] args) {}
}
The result is:
public
The same happens regardless of constructor modifier (public, protected, private) or parameters type (primitive or reference). How could it be, whereas “transient” is not valid modifier for constructor?
Access modifiers are encoded as bit masks inside the class file. The JVM spec assigns different meaning to some of the bits depending on whether they appear in a method modifier or a field modifier. Bit 7 (
0x0080) is one such bit.For methods:
For fields:
Since you’re looking at a method, the correct interpretation of this modifier is
ACC_VARARGSand notACC_TRANSIENT.However, the
Modifierclass only appears capable of dealing with a subset of modifiers defined in the JVM spec. Because all it takes is anint, it’s unable to tellACC_VARARGSandACC_TRANSIENTapart.