[英]Object, reference and class. Need help understanding some code
我有点理解:
两次调用以下代码会发生什么?
Car batmobile = new Car();
是否会创建两个对象? 如果是这样,第一个对象发生了什么? 详细地说,在类,对象和引用方面会发生什么?
第2部分:
这是一个无限循环吗? 自构造函数创建对象以来,对象会继续创建吗? 类,对象,引用关系在这里如何工作?
public class Alphabet {
Alphabet abc;
public Alphabet() {
abc = new Alphabet();
}
}
汽车batmobile = new Car(); 是否会创建两个对象?
如果调用两次,则为是。 因为该行创建了一个对象的新实例。 因此,执行两次将导致两个新实例。 但是请注意,如果您尝试连续两次执行相同的确切行,则会出现编译器错误,因为您将尝试在同一作用域中重新声明相同的变量。
但是否则,不会,在该行上仅创建一个对象。 两次提到Car
是因为它声明了变量( batmobile
)和构造函数( Car()
)的类型。 某些语言(C#,JavaScript,无类型语言等,但Java没有)具有速记功能,因为很容易从第二种语言推断出来。 例如:
var batmobile = new Car();
这是一个无限循环吗?
不,这里没有循环:
Public class Alphabet{
Alphabet abc;
Public Alphabet(){
abc = new Alphabet();
}
}
有 ,然而,一个堆栈等待飞越。 为了创建一个Alphabet
必须首先创建一个Alphabet
。 运行代码,然后查看错误。 无限循环将无限执行(假设循环的每次迭代都不会增加某些有限资源的使用),例如:
while (true) {
Car batmobile = new Car();
}
这将无休止地执行。 但是,您发布的代码将结束。 有错误。 因为每次对构造函数的调用都会在内部调用构造函数。 调用堆栈是有限的资源,因此它将很快耗尽。
我用一个cookie隐喻来解释对象和类。
将计算机的内存想像成一大堆饼干面团。 (好吃,不是吗?)
您的课程是小甜饼刀。 只要您有面团(记忆),它将创建特定大小和形状的Cookie。 一个对象是用cookie切割器剪切的cookie。
1)batmobile是对Car对象的引用。 它只能指向Car或car的子类。 创建对象时,没有附加对象实例(面团)。 调用new Car()时,将对象实例标记出来,并将其分配给名为batmobile的引用。 只有一个参考。
2)不要这样做。 我不确定,您可能最终会导致堆栈溢出,但这不会为您带来所需的结果。 您可能要查找Singleton模式。 它可能会帮助您。
现在,我需要帮助来了解两次调用此代码时究竟发生了什么。
例如:
Car batmobile = new Car();
是否会创建两个对象?
每次执行该行时,都会创建一个Car
对象,因此,如果执行两次,则将创建两个对象。
如果是这样,第一个对象发生了什么。
如果没有其他引用,JVM就有资格对其进行垃圾回收。 何时以及是否发生这种情况取决于JVM的垃圾收集器中的许多因素。
有人可以详细解释在类,对象和引用方面会发生什么。
Car batmobile
...声明一个Car
类型的变量。 因为它是对象类型,所以该变量最终将保存对象引用 (或null
,这意味着它不保存对任何对象的引用)。 实际对象独立于可能引用它的任何变量而存在(并且可能有多个引用到一个对象)。 对象引用就像一个内存地址,说明对象在内存中的位置。 (它不是一个内存地址,但是就像一个。)
new Car();
...创建一个新的Car
对象,并调用Car
构造函数对其进行初始化。 所以:
Car batmobile = new Car();
...声明一个变量,创建一个对象,调用Car
构造函数,并将对该对象的引用分配给batmobile
。
这是一个无限循环吗?
可能会,但是最终您会耗尽堆栈空间,因此这是一个堆栈溢出错误 。 该行调用了Alphabet
构造函数,该函数调用了Alphabet
构造函数,该函数又调用了Alphabet
构造函数...您明白了。
问题1
Car batmobile = new Car();
这将创建一个对象。 该对象为Car
类型,其标识符为“ batmobile”。 根据其引用, batmobile
将被弹出到堆栈上,并且将包含对堆上Car
类型的对象的引用。
这个问题可能对堆栈和堆内存的解释有所帮助。
问题2
具有讽刺意味的是,看到此示例已发布在SO上,则此示例将导致堆栈溢出错误。 每次对构造函数的调用都会创建一个新对象,并将对该对象的引用放在堆栈上,然后再次调用该构造函数。 堆栈是内存有限的区域,因此最终它将溢出,并且您的程序将因堆栈溢出错误而终止
在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
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.