When is it OK to create object of a class inside a

2019-03-14 13:01发布

问题:

public class TestClass(){
    public static void main(String []args) {
        TestClass t1 = new TestClass();
        t1.anything();
    }
}

Is it not strange to create a object in the definition of same class? Because then in response - this object creates a new object, then this new object creates another, and the infinite loop begins to never end until the memory is full.

回答1:

Is it not strange to create an object in the definition of the same class than in response the object create a new object then this new object create another and the infinite loop begins

No, the main method only runs once when you run your program. It will not be executed again. So, the object will be created only once.

Think of your main method to be outside your class. Which creates an instance of your class, and uses the instance created. So, when you create an instance from main method, the constructor is invoked to initialize the state of your instance, and then when the constructor returns, the next statement of your main method is executed.

Actually, you can consider main method not to be a part of the state of the instance of your class.

However, had you created the instance of your class inside your constructor (say 0-arg), and the reference as instance reference variable, then that will turn into an infinite recursion.

public class A {
    private A obj;
    public A() {
        obj = new A();  // This will become recursive creation of object.
                        // Thus resulting in StackOverflow 
    }
}


回答2:

You would only have an infinite loop (stack overflow error) if you tried to do the below:

public class TestClass {
    public TestClass() {
        TestClass t = new TestClass();
    }
}

And elsewhere, you try to create an object of the class TestClass.



回答3:

It's not really odd. All object oriented languages that I am aware of allow this. The code is semantically part of the object definition, but in practice it can be considered separate from the actual state of any given object. So there is no loop because object construction doesn't call your method (unless, of course, it does - then you have a problem).



回答4:

When you use new to create object constructors are called which initializes the instance variable this happens till all the constructors of your super class have been called . if you put the some code inside constructor that will run each time you create an object



回答5:

When a program starts it executes the main method. In java you cannot create a method outside of a class. All methods must be encapsulated within a class. Therefore the main method as an entry point to the program must be within a class. When you run this program the main method will be run once and will execute the code inside it. In your case it creates an object of the enclosing class TestClass. This does not have to happen. It can create objects outside of this class as well. You will only get an infinite loop as explained in the @adarshr's answer.



回答6:

public class TestClass{
  public static void main(String []args) {
    TestClass t1 = new TestClass();
    t1.anything();
  }
}

This is a perfectly valid code. When the main method is called, no prior instance of the TestClass exists (it needs not, because the main method is static).

public class Test2{
  public Test2 clone(){
    return new Test2();
  }
}

This is perfectly valid as well. When you create a new instance of Test2, it contains the clone method, but the method is not automatically executed. Only when the clone method is called, one more instance of Test2 is created.

public class MyLinkedList{
  MyLinkedList next;
  MyLinkedList(int elems){
    if(elems>0){
      next = new MyLinkedList(elems-1);
    }else{
      next = null;
    }
  }
}

is perfectly valid as well, even if the constructor creates a new instance using the same constructor, because the creation is guarded by a conditional, so creating an instance sometimes triggers a new creation.

public class Fail{
  public Fail(){
    new Fail();
  }
}

Is the only problematic example here. The compiler doesn't complain. It can be translated into byte code and it can be executed. At the runtime, however, you cause a stack overflow:

  • a new Fail is allocated
  • its no-arg constructor is called
  • the constructor tries to create a new Fail
  • a new Fail is allocated
  • its no-arg constructor is called
  • ...

The compiler allows this, because, in general, the compiler cannot prevent all infinite recursion. The compiler allows anything that can be translated into bytecode.

The compiler, however, may issue a warning if it detects a method or a method chain calls itself unconditionally.



标签: java class