Why can a Java static method call a constructor, but not refer to this?

13,857

Solution 1

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.

Solution 2

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.

Solution 3

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.

Share:
13,857
Max Abrahamsson
Author by

Max Abrahamsson

Updated on June 05, 2022

Comments

  • Max Abrahamsson
    Max Abrahamsson almost 2 years

    My Assumptions:

    1. Static method cannot cannot call non-static methods.
    2. Constructors are kind of a method with no return type.

    Given this example...

        public class Main {
            public static void main(String[] args) {
                Main p = new Main();  // constructor call
                k();  // [implicit] `this` reference
            }
    
            protected Main() {
                System.out.print("1234");
            }
    
            protected void k() {
            }
        }
    
    • this line prints 1234: Main p = new Main()
    • this line throws an Exception: k()

    Why did the example code do those two things? Don't they conflict with my above Assumptions? Are my Assumptions correct?