Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected "transient" constructor modifier

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?

like image 519
Grade Avatar asked Jan 05 '13 10:01

Grade


People also ask

Which access modifier is allowed for a constructor?

Like methods, constructors can have any of the access modifiers: public, protected, private, or none (often called package or friendly). Unlike methods, constructors can take only access modifiers. Therefore, constructors cannot be abstract , final , native , static , or synchronized .

What is the modifier of the constructor of an abstract class?

The constructor(s) of an abstract class can have the usual access modifiers (public, protected, and private (for internal use)).

Which of the following modifier combination is legal?

Only A and D are legal.

Can constructor throw an exception?

Yes, constructors are allowed to throw an exception in Java. A Constructor is a special type of a method that is used to initialize the object and it is used to create an object of a class using the new keyword, where an object is also known as an Instance of a class.


1 Answers

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:

ACC_VARARGS    0x0080  Declared with variable number of arguments.

For fields:

ACC_TRANSIENT  0x0080  Declared transient; not written or read by a persistent
                       object manager.

Since you're looking at a method, the correct interpretation of this modifier is ACC_VARARGS and not ACC_TRANSIENT.

However, the Modifier class only appears capable of dealing with a subset of modifiers defined in the JVM spec. Because all it takes is an int, it's unable to tell ACC_VARARGS and ACC_TRANSIENT apart.

like image 63
NPE Avatar answered Oct 27 '22 11:10

NPE