繁体   English   中英

对象,引用和类。 需要帮助了解一些代码

[英]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();
}

将会发生以下情况:

  1. 创建新的Alphabet实例
  2. 调用Alphabet的构造函数(从main方法)
  3. 创建新的Alphabet实例(分配给成员变量abc
  4. 调用Alphabet的构造函数(来自Alphabet的构造函数)
  5. 继续递归(步骤3-4),直到发生StackOverflowError

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM