Why can a Java static method call a constructor, but not refer to this?
Rules are simple:
1 - Static method cannot cannot call non-static methods.
That's simply not true. A static method can call a non-static method, just via a "target" reference. For example, this is fine in a static method:
Integer x = Integer.valueOf(10);
int y = x.intValue(); // Instance method!
The real point is "there's no this
reference within a static method".
2 - Constructors are kind of a method with no return type.
That's not a really useful model, to be honest. It makes more sense (from the caller's point of view) to consider a constructor as a static method with a return type that's the same as the declaring class, but even that's not a perfect model by any means.
I suggest you think of a constructor as a different type of member. Embrace the differences between constructors and methods, instead of trying to hide them.
1 - Static method cannot cannot call non-static methods.
Sure they can, but they need an object to call the method on.
In a static method, there's no this
reference available, so foo()
(which is equivalent to this.foo()
) is illegal.
2 - Constructors are kind of a method with no return type.
If they should be compared to methods, I would say constructors are closer to non-static methods (since there is indeed a this
reference inside a constructor).
Given this view, it should be clear to you why a static method can call a constructor without any problems.
So, to sum it up:
Main p = new Main();
is okay, since new Main()
does not rely on any existing object.
k();
is not okay since it is equivalent to this.k()
and this
is not available in your (static) main method.
No. Constructors aren't ordinary methods in this respect. The whole point of the constructor is to, well, construct a new instance of the class.
So it can be invoked in static scope too. Just think about it: if you needed an existing instance of your class in order to create a new instance of it, you would simply never be able to instantiate it ever.
A few clarifications:
Static method cannot cannot call non-static methods.
Not quite. You can call a nonstatic method from inside a static method, just you need to scope it to a specific object of that class. I.e.
p.k();
would work perfectly in your code sample above.
The call
k();
would be fine inside an instance (nonstatic) method. And it would be equivalent to
this.k();
The implied this
refers to the current instance of the class. Whenever the compiler sees an unqualified call like k()
within an instance method, it will automatically scope it with this.
. However, since static methods aren't tied to any instance of the class, you (and the compiler) can't refer to this
inside a static method. Hence you need to explicitly name an instance of the class to call an instance method on.