Question

I am going through Thinking in Java by Bruce Eckel 4th Edition. In the chapter Initialization & Cleanup, page : 189 the first bullet point in the second para mentions:

Even though it doesn't explicitly use the static keyword the constructor is actually a static method.

I have the following piece of code:

class Bar {
    Bar() {
        System.out.println("Bar Creation");
    }
}

class Foo {
    static int x = 10;
    static Bar b = new Bar();

    Foo() {
        System.out.println("Foo Creation");
    }
}

public class Test { 
    public static void main(String[] args) {
        System.out.println(Foo.x);
    }
}

If what it says is true The constructor for Foo should have been called. I don't see that happening with the following piece of code.

The output is:

Bar Creation
10

Can someone clarify what does it mean?

I have tried my best to quote the book. I don't think the parts previous to that statement or after that have much relevance to this statement in context of the question.

Thanks,

Gudge

Was it helpful?

Solution

There's no reason for Foo() to be called just because you mentioned the class. Static initializers like static Bar b = new Bar(); are called when the class is loaded; static methods are called by your code.

I would guess that what the book means is that constructors are like static methods in that the dispatch is static: that is, there is no way to inherit and override a constructor, and a call site for a constructor, or a static method, always refers to some specific class determined at compile time.

(This staticness of constructors is the motivation for “factory” objects which construct objects in their instance methods.)

OTHER TIPS

Simply because you haven't created new instance of Foo to access static field x of it

If you had created new Foo() the constructor code would have got called. Since x is a static member field, its not required to create the instance of the holder class to access that field.

Another way of accessing x is new Foo().x, but the new Object creation is unnecessary.

And the reason why "Bar Creation" got printed is, because A static field declared by Foo is assigned. See JLS 12.4.1 for the initialization specs

Unless you call new() on Foo class, constructor will not be called. As new keyword internally calls the constructor. You are simply accessing a static field of the class using its name for that you don't need to create an instance.

A constructor is called after a new object is created. I wouldn't call it a static method as it must have an instance and that instance is accessible via default this

public class Main {
    public Main() {
        // static methods do not have a `this`
        System.out.println("Main called" + this.getClass());
    }

    public static void main(String... ignore) {
        new Main();
    }
}

If you decompile the byte code, you can see static methods

$ javap -c -p -cp . Main
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       7: new           #3                  // class java/lang/StringBuilder
      10: dup           
      11: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      14: ldc           #5                  // String Main called 
      16: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: aload_0       
      20: invokevirtual #7                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
      23: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      26: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      29: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      32: return        

  public static void main(java.lang.String...);
    Code:
       0: new           #11                 // class Main
       3: dup           
       4: invokespecial #12                 // Method "<init>":()V
       7: pop           
       8: return        
}

Note: static methods have a different modifier.

You're newer newing up Foo, instead you're newing up Bar as a static field in Foo. You can access static variables in a class without ever constructing an instance of it.

The constructor is only called when you use the new keyword. Since you don't do new Foo(), the constructor isn't called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top