Take this simple class...
public class Gen
{
public static void main (String[] Args)
{
Gen genny = new Gen();
}
}
Section 8.8.9 of the JLS states that "If a class contains no constructor declarations, then a default constructor is implicitly declared." It also says that as long as we're not in the java.lang.object
class, then the "default constructor simply invokes the superclass constructor with no arguments."
So because the class Gen
extends java.lang.object
, we are forced to call java.lang.object
's constructor through super()
as part of the implicitly-created default constructor.
Likewise...
public class Gen extends Object
{
public static void main (String[] Args)
{
Gen genny = new Gen();
}
public Gen()
{
}
}
Even if we explicitly declare a constructor for Gen
, Section 8.8.7 of the JLS mandates that "if a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object
, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments."
So once again, Java is going above and beyond to get us to call java.lang.object
's constructor through super()
. But java.lang.object
's constructor literally has an empty body. It doesn't do anything. A constructor has actual purpose only 1) if you write it such that it initializes a class' instance variables or 2) if it directly/indirectly calls its superclass(es)'s constructors to initialize their instance variables. java.lang.object
's constructor does neither of these things because it 1) has no instance variables and 2) is the root of the inheritance hierarchy. So it's a pointless constructor. And now, in our class Gen
, we are being pointlessly forced to call a pointless constructor.
Why do this? Why can't the Java people just say "right, if the class is a direct subclass of java.lang.object
then we won't implicitly define a constructor and neither will we implicitly call super()
if a constructor explicitly exists." Honestly, why even have a constructor for java.lang.object
in the first place if it's gonna be empty?
CodePudding user response:
First of all, it is NOT necessary to write this:
public class Gen extends Object {
If a class doesn't explicitly have some other class as its direct superclass, then it implicitly extends Object
. There is not need to tell the compiler that.
Yes ... all classes (apart from Object
) constructors will call a constructor of their superclass. Even if the superclass is Object
.
But it doesn't matter to the programmer. As the spec says, if the constructor to be called is a no-args constructor, then you don't need an explicit super
call. The compiler injects a missing super()
call for you if you don't include one.
Yes ... the Object
constructor has an empty body in all Java implementations I have come across.
But I don't think that the JLS mandates that.
The JLS section on how objects are created states that the constructor will be called.
But it doesn't say that the compilers can't optimize away the call to the Object()
constructor. And that is what they do. (The bytecode compiler is required to emit instructions for the call by JVM spec, but the JIT compiler can and will optimize it away.)
Why do they specify it in these terms?
Primarily because the spec is easier to understand and the language is easier to use if there are fewer special cases in the Java syntax and semantics.
"You can't have a
super()
class if the superclass isObject
" would be a special case. But this complexity is not needed to make the language work, and it certainly doesn't help programmers if you force them to leave out asuper()
call in this context.In addition, the current way permits a Java implementation to have a non-empty
Object()
constructor, if there was a good reason for doing that. (But I doubt that that was serious consideration when they designed Java.)
Either way, this is the way that Java has been since before Java 1.0, and they won't change it now. The current way doesn't actually cause any problems, or add any appreciable overheads.