簡體   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