什么时候可以在该类的方法中创建类的对象?

Rav*_*try 21 java class

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

在同一个类的定义中创建一个对象并不奇怪吗?因为然后作为响应 - 这个对象创建一个新对象,然后这个新对象创建另一个,并且无限循环开始永远不会结束,直到内存已满.

Roh*_*ain 23

在同一个类的定义中创建一个对象比在响应中创建一个新对象并不奇怪,然后这个新对象创建另一个并且无限循环开始

不,主程序只在您运行程序时运行一次.它不会再被执行.因此,该对象只会创建一次.

想想你在课堂外的主要方法.这将创建您的类的实例,并使用创建的实例.因此,当您从main方法创建实例时,将调用构造函数来初始化实例的状态,然后在构造函数返回时,执行main方法的下一个语句.

实际上,您可以认为main方法不是您的类实例状态的一部分.

但是,如果您在构造函数(例如0-arg)中创建了类的实例,并将引用作为实例引用变量,那么这将转变为无限递归.

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


ada*_*shr 5

如果您尝试执行以下操作,则只会出现无限循环(堆栈溢出错误):

public class TestClass {
    public TestClass() {
        TestClass t = new TestClass();
    }
}
Run Code Online (Sandbox Code Playgroud)

在其他地方,你试图创建一个类的对象TestClass.


Joh*_*rak 5

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

这是一个完全有效的代码。main当调用该方法时,不TestClass存在 的先前实例(不需要,因为该main方法是static)。

public class Test2{
  public Test2 clone(){
    return new Test2();
  }
}
Run Code Online (Sandbox Code Playgroud)

这也是完全有效的。当您创建 Test2 的新实例时,它包含该clone方法,但该方法不会自动执行。仅当clone调用该方法时,才会创建另一个 Test2 实例。

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

即使构造函数使用相同的构造函数创建一个新实例,也是完全有效的,因为创建是由条件保护的,所以创建实例有时会触发新的创建。

public class Fail{
  public Fail(){
    new Fail();
  }
}
Run Code Online (Sandbox Code Playgroud)

这是这里唯一有问题的例子。编译器不会抱怨。它可以被翻译成字节码并且可以被执行。然而,在运行时,您会导致堆栈溢出:

  • 分配了一个新的失败
  • 它的无参数构造函数被调用
  • 构造函数尝试创建一个新的 Fail
  • 分配了一个新的失败
  • 它的无参数构造函数被调用
  • ...

编译器允许这样做,因为一般来说,编译器无法阻止所有无限递归。编译器允许任何可以翻译成字节码的东西

但是,如果编译器检测到方法或方法链无条件调用自身,则可能会发出警告