2

I have some doubt on how this works, consider a simple Java program:

package com.example;

public class Test {

    public static void main(String[] args) {

        Test t = new Test();  (1) <---- How is this possible
        t.print();
    }

    public void print() {
        System.out.println("This is demo");
    }
}

This is pretty straightforward program.

However, I have doubt at (1). We are creating an instance of Test, but this is still in the definition of Class Test. How is this possible?

Any explanation to help this would be great.

CuriousMind
  • 8,301
  • 22
  • 65
  • 134
  • Why do you think this shouldn´t be possible? This might help to clear your doubts. – SomeJavaGuy Mar 11 '16 at 06:26
  • It is like you are still a "class" and creating object, when the definition of class is yet in defining stage... that is why I have difficult in understanding this. – CuriousMind Mar 11 '16 at 06:31
  • I think it might cause error if you put in the constructor. It should still be fine inside the method. Just imagine that class is the parent, the object is the child. And the child may ask his siblings to help him do something when he invokes a method. – Shaohua Huang Mar 11 '16 at 06:31
  • @CuriousMind - did you get your question answered? The key concept is ["static"](http://stackoverflow.com/questions/413898/). A static method is "special", it exists independent of any particular "object" (aka "class instance"). Please see my updates below. – paulsm4 Mar 19 '16 at 20:05

3 Answers3

2

The instance will be created at run-time.

By then, compile-time is over and all of the code of your application (including all class definition) will be "ready".

Even if you call a constructor of a class that has not been encountered by the JVM up to that point, it will dynamically load the class (in its entirety) before executing the constructor call. Note that a) this might actually fail at run-time, in which case you get a ClassNotFoundError, and b) that cannot happen in your case, because you are calling the constructor of the class from itself (so it must have been loaded already).

The compiler does not run any of your code (not even things like static initializers) during compilation.

But it does make sure (during compilation) that every method or constructor that you are trying to call does in fact exist. Again, this could theoretically fail at runtime (if you mess up class files), in which case you would get a NoSuchMethodError.

Thilo
  • 257,207
  • 101
  • 511
  • 656
1

Q: Test t = new Test(); (1) <---- How is this possible

A: Because of the "static" in public static void main(String[] args)

The "static" means that method "main()" is independent of any specific class object.

You can create any class object you want - including a new "Test" object.

One of the benefits of defining "main" to be static is that you can use "main()" as a test method for the class. Each class can have it's own "main", and you can test each class individually by specifying that class in your Java command line.

For example:

public class MyClass {

  public int add2(int n) {
    return n + 2;
  }

  public static void main (String[] args) {
    MyClass unitTest = new MyClass ();
    System.out.println ("add2(2)=" + unitTest.add2(2));
    System.out.println("Expected result=4");
  }
}

Then test as follows:

javac MyClass.java
java MyClass 

add2(2)=4
Expected result=4

This question has actually been asked and answered many times. For example:

Why is the Java main method static?

==================================================================

Here are a few more examples that illustrate the point:

public class CreateMyself {

  private int value = 0;
  private static CreateMyself m_singleton = null;

  // EXAMPLE 1: You can legally create an instance in the constructor ... 
  public CreateMyself () {
    value++;
    // CreateMyself o = new CreateMyself ();  // BAD!!! This will cause infinite recursion and crash your stack!!!
    System.out.println ("Leaving constructor, value=" + value + "...");
  }

  // EXAMPLE 2: You can legally create another instance in a normal class member     
  public void createAnother() {
    // But ... WHY???  Is there anything you can't do directly, in your own instance?
    CreateMyself newInstance = new CreateMyself ();
    System.out.println ("Leaving createAnother, value=" + value + "...");
  }

  // EXAMPLE 3: This is a common idiom for creating a "singleton"
  // NOTE: for this to work, you'd also make the constructor PRIVATE (or protected), so the client *must* call "getInstance()", instead of "new".
  public static CreateMyself getInstance () {
    if (m_singleton == null) {
      m_singleton = new CreateMyself ();
    }
    System.out.println ("returning singleton instance...");
    return m_singleton;
  }

  // EXAMPLE 4: Creating an instance in "static main()" is a common idiom
  public static void main (String[] args) {
    CreateMyself newInstance = new CreateMyself ();
    newInstance.createAnother ();
  }

}

There are many other possible uses. For example, maybe you'll have a static method that does a database lookup and returns a list matching objects.

Note that most of the cases where it's really useful for a class to have a method where it creates an instance of itself are probably static methods.

Community
  • 1
  • 1
paulsm4
  • 114,292
  • 17
  • 138
  • 190
1

First We have to Compile this Porgram using javac After Compilation It will give a Class File.

Now time to Execute Your Class Using java which Invokes JVM and load the Class File to the Class Loader.

java fileName.Class

And here

 public static void main(String[] args) {

        Test t = new Test();  (1) <---- How is this possible
        t.print();
    }

All we know static Content (either it is Variable or Method In Java) Of class loaded when ClassLoader loads a Class

As You see Main Method is a static Method. and So, It will Automatically Load into the ClassLoader with class File.

Now JVM First find the public static void main(String... args) in class. Which is a static Content means Its a part of Class but not a part of Class Instance. There is no need of Class Instance to Invoke this MainMethod`.

main(String... args) will be Invoked without getting Instance of the Class. In that Main Method , Your Class is Getting Instantiated

 Test t = new Test(); \\here t is reference Variable to Test Class Object.

Now Because Class is loaded into the class Loader new Test(); will create a New Object in Heap memory Area of JVM and your method

 public void print() {
        System.out.println("This is demo");
    }

will be invoked using t.print() Which is a Instance Method (Not Static), So It needs Class Instance to Invoke print() Method.

Vikrant Kashyap
  • 6,398
  • 3
  • 32
  • 52