AFAIK, in Java implicit constructors are always generated for a class without constructors [1], [2].
But in bytecode I could not find such restriction on the JVMS.
It is legal. The JVMS does not say otherwise.
Sometimes, the Java compiler does even create such classes in order to create accessor constructors for inner classes:
class Foo {
{ new Bar(); }
class Bar() {
private Bar() { }
}
}
In order to make this private constructor accessible to the outer clasd, the Java compiler adds a package-private constructor to the inner class that takes an instance of the randomly created constructor-less class as its single argument. This instance is always null and the accessor only invokes the parameterless constructor without using the argument. But because constrors cannot be named, this is the only way to avoid collissions with other constructors. In order to keep the class file minimal, no constructor is added.
On a side note: It is always possible to create instances of classes without constructors. This can be achieved by, for example, absusing deserialization. If you use Jasmin to define a class without a constructor that implements the Serializable
interface, you can create a byte stream manually that resembles the class if it was serialized. You can than deserialize this class and receive an instance of it.
In Java, a constructor call an an object allocation are two seperate steps. This is even exposed by the byte code of creating an instance. Something like new Object()
is represented by two instuctions
NEW java/lang/Object
INVOKESPECIAL java/lang/Object <init> ()V
the first being the allocation, the second being the constructor's invocation. The JVM's verifier always checks that a constructor is called before the instance is used but in theory, the JVM is perfectly capable of detaching both, as proven by deserialization (or internal calls into the VM, if serialization is not an option).
You've already answered the question yourself: a class without a constructor is absolutely valid according to JVMS. You cannot write such a class in pure Java, but it can be constructed using bytecode generation.
Think of interfaces: they are also classes without a constructor from JVM point of view. And they can also have static members (you can even invoke interface's main
method from the command line).