According to John C. Mitchell - Concepts in programming languages,
[...] Java guarantees that a constructor is called whenever an object is created.
In Java there are some situations when the constructor is not called.
For example when a class is deserialized, the default constructor of the first non-serializable class in the type hierarchy will be called, but not the constructor of the current class. Also Object.clone
avoids calling the constructor. You can also generate bytecode and do it yourself.
To understand how this is possible, even without native code magic inside the JRE, just have a look at the Java bytecode. When the new
keyword is used in Java code, two bytecode instructions are generated from it - first the instance is allocated with the new
instruction and then the constructor is called with the invokespecial
instruction.
If you generate your own bytecode (for example with ASM), it's possible change the invokespecial
instruction to call the constructor of one of the actual type's super classes' constructor (such as java.lang.Object
) or even completely skip calling the constructor. The JVM will not complain about it. (The bytecode verification only checks that each constructor calls its super class's constructor, but the caller of the constructor is not checked for which constructor is called after new
.)
You can also use the Objenesis library for it, so you don't need to generate the bytecode manually.