我有点明白:
下面的代码被调用两次时到底发生了什么?
Car batmobile = new Car();
是否会创建两个对象?如果是这样,第一个对象会发生什么? 详细说明,在类,对象和引用方面会发生什么?
第2部分:
这是一个无限循环吗?因为构造函数创建一个对象然后再次调用构造函数,是否会继续创建对象?类,对象,引用关系如何在这里工作?
public class Alphabet {
Alphabet abc;
public Alphabet() {
abc = new Alphabet();
}
}
答案 0 :(得分:2)
Car batmobile = new Car();是否会创建两个对象?
如果它被称为两次那么是。因为该行创建了一个对象的新实例。这样做两次会导致两个新实例。但请注意,如果您尝试连续两次执行相同的确切行,则会出现编译器错误,因为您试图在同一范围内重新声明相同的变量。
但是否则,不,那条线上只创建了一个对象。 batmobile
被提及两次,因为它声明了变量(Car()
)和构造函数(var batmobile = new Car();
)的类型。有些语言(C#,JavaScript,无类型语言等但不是Java)在第一次使用时有简写,因为它很容易从第二种语言中推断出来。例如:
Public class Alphabet{
Alphabet abc;
Public Alphabet(){
abc = new Alphabet();
}
}
这是一个无限循环吗?
不,这里没有循环:
Alphabet
是,但是,堆栈等待溢出。要创建Alphabet
,必须先创建while (true) {
Car batmobile = new Car();
}
。运行代码并查看错误。无限循环只会无限执行(假设循环的每次迭代都没有使用某些有限资源),例如:
{{1}}
这将无止境地执行。但是,您发布的代码将结束。有错误。因为每次对构造函数的调用都在内部调用构造函数。调用堆栈是一个有限的资源,因此很快就会耗尽。
答案 1 :(得分:1)
我使用cookie比喻来解释对象和类。
将计算机的记忆想象成一块饼干面团。 (好吃,不是吗?)
你的班级是一个千篇一律。只要你有面团(记忆),它就会创造出特定大小和形状的饼干。一个物体是用饼干切割器切割的饼干。
1)batmobile是对Car对象的引用。它只能指向汽车或汽车的子类。它在创建时没有附加对象实例(面团)。当您调用新的Car()时,您将标记一个对象实例并将其分配给名为batmobile的引用。只有一个参考。
2)不要这样做。你可能最终会出现堆栈溢出,我不确定,但它不会得到你想要的结果。您可能想要查找Singleton模式。它可能会对你有帮助。
答案 2 :(得分:0)
现在我需要帮助了解在两次调用此代码时究竟发生了什么。
例如:
Car batmobile = new Car();
是否会创建两个对象?
每次执行该行时都会创建一个Car
对象,所以如果执行两次,是的,就会创建两个对象。
如果是这样,第一个对象会发生什么。
如果没有其他内容可以引用它,它就有资格通过JVM进行垃圾回收。何时以及是否发生这种情况取决于JVM垃圾收集器中的许多因素。
有人可以详细解释在课程,对象和参考方面会发生什么。
Car batmobile
...声明类型为Car
的变量。因为它是一个对象类型,变量最终会持有一个对象引用(或null
,这意味着它没有持有对任何对象的引用)。实际对象独立于任何可能引用它的变量(并且可能有许多对一个对象的引用)。对象引用是 like 一个内存地址,说明对象在内存中的位置。 (不一个内存地址,但它就像一个。)
new Car();
...创建一个新的Car
对象并调用Car
构造函数来初始化它。所以:
Car batmobile = new Car();
...声明一个变量,创建一个对象,调用Car
构造函数,并将该对象的引用分配给batmobile
。
这是一个无限循环吗?
它会,但最终你会耗尽堆栈空间,因此它是堆栈溢出错误。该行调用Alphabet
构造函数,该构造函数调用Alphabet
构造函数,该构造函数调用Alphabet
构造函数...您明白了。
答案 3 :(得分:0)
问题1
Car batmobile = new Car();
这会创建一个对象。该对象的类型为Car
,其标识符为“batmobile”#39;就其引用而言,batmobile
将被弹出到堆栈上,它将包含对堆上类型为Car
的对象的引用。
这个question可能有助于堆栈和堆内存解释。
问题2
具有讽刺意味的是,看到这个在SO上发布,这个例子会导致堆栈溢出错误。每次调用构造函数都会创建一个新对象,并在再次调用构造函数之前将对它的引用放在堆栈上。堆栈是一个内存有限的区域,因此最终会溢出,程序将以堆栈溢出错误终止
答案 4 :(得分:0)
在C ++中,当你写:
SomeClass x;
它会自动创建SomeClass
的实例。在Java中不是这样。
在Java中,上面的同一行只是创建一个名为x
的变量,其类型为SomeClass
。在初始化为某些内容之前,变量x
不引用任何内容(任何实例)。
在Java中,下面的行创建了一个对象并初始化变量x
以指向它。
SomeClass x = new SomeClass();
您的代码块:
Public class Alphabet{
Alphabet abc;
Public Alphabet(){
abc = new Alphabet();
}
}
实际上没有做任何事情,因为从不调用构造函数。如果你这样称呼它:
public static void main(String[] args){
new Alphabet();
}
以下情况会发生:
main
方法)abc
)