簡體   English   中英

`new`關鍵字做什么

[英]What does the `new` keyword do

我正在線上學習Java教程,試圖學習這門語言,並且它在使用數組的兩種語義之間蹦蹦跳跳。

long results[] = new long[3];
results[0] = 1;
results[1] = 2;
results[2] = 3;

和:

long results[] = {1, 2, 3};

教程從未真正提到為什么它在兩者之間來回切換,所以我對這個主題進行了一些搜索。 我目前的理解是new運算符正在創建一個“longs數組”類型的對象。 明白的是為什么我想要那個,那有什么后果?

  • 除非它是“數組對象”,否則某些“數組”特定方法不適用於數組?
  • 對於我可以用普通數組做的“數組對象”,我有什么不能做的嗎?
  • Java VM是否必須清理使用new運算符初始化的對象,而這通常不需要執行?

我來自C,所以我的Java術語在這里可能不正確,所以如果某些事情不可理解,請要求澄清。

在Java中,所有數組和對象都在堆上分配,因此從某種意義上說,所有數組都是“數組對象”。 在Java中堆棧上唯一分配的東西是對象引用和原語。 其他所有內容都是在堆中定義和分配的對象,包括數組,無論您使用哪種語法來聲明它。 (您的兩個示例在最終結果中是等效的,請參閱JLS§10.3及其鏈接部分,以獲取有關如何實際分配和分配每個示例的更多信息。)

這與C / C ++相反,在C / C ++中,您可以顯式控制堆棧和堆分配。

請注意,Java在短期對象分配/釋放方面非常快。 由於其基於生成的垃圾收集器,它非常高效。 那么回答你的問題:

除非它是“數組對象”,否則某些“數組”特定方法不適用於數組? 對於我可以用普通數組做的“數組對象”,我有什么不能做的嗎?

沒有數組不是對象,所以沒有。 ,但是,這不會對原始陣列工作方式。 采用Object[]方法不會先接受long[]而不先將其轉換為Long[] 這是由於Java 5及更高版本中的自動裝箱的一些實現細節。

Java VM是否必須清理使用new運算符初始化的對象,而這通常不需要執行?

任何用new分配的東西最終都必須被垃圾收集,所以在做任何事情時通常都不會這樣做? 否。但是,請注意,在C / C ++,分配使用數組malloc / new意味着你也有free / delete []它,這是你沒有用Java做的,因為它會收回該陣列為你。

請注意,如果在方法中聲明了long[] ,並且從未將其存儲在方法之外的某個引用中,則會在方法調用結束時自動將其標記為垃圾回收。 垃圾收集器將等待回收它的空間直到它需要它,但你不必通過delete [] (或對象的delete和析構函數)自己進行任何回收。

編輯:承諾的一些參考:

Java中的new關鍵字創建一個新對象。 在這種情況下,它創建一個數組...這是一個對象。

這兩種形式是等同的。 第二個是第一個方便的簡寫。 它是語法糖

除非它是“數組對象”,否則某些“數組”特定方法不適用於數組?

所有數組都是對象。 期。

對於我可以用普通數組做的“數組對象”,我有什么不能做的嗎?

往上看。

Java VM是否必須清理使用new運算符初始化的對象,而這通常不需要執行?

沒有。就JVM而言,以不同方式創建的對象之間沒有區別。

這兩個在創建的數組的行為方面是相同的。 所有數組在技術上都是java中的對象; 這些只是初始化它們的兩種不同方式。 也可以將兩者結合起來:

long[] results = new long[]{1,2,3};

兩者都是一樣的。 第二個選項是隱式創建數組對象,它只是為了方便用戶。

來自JLS#Chapter 10. Arrays

在Java編程語言中,數組是對象(§4.3.1),是動態創建的,可以分配給Object類型的變量(§4.3.2)。 可以在數組上調用Object類的所有方法。

10.3. Array Creation 10.3. Array Creation

數組由數組創建表達式(第15.10節)或數組初始值設定項(第10.6節)創建

15.10. Array Creation Expressions 15.10. Array Creation Expressions

數組創建表達式創建一個對象,該對象是一個新數組,其元素的類型是PrimitiveTypeClassOrInterfaceType指定的類型。

10.6. Array Initializers 10.6. Array Initializers

可以在聲明(第8.3節,第9.3節,第14.4節)中指定數組初始值設定項,或者作為數組創建表達式(第15.10節)的一部分,以創建數組並提供一些初始值。

兩者都初始化數組,差異是第二個用一些值初始化。

您展示的兩種創作方式是等效的。 兩者都是“數組對象” - 請記住,Java中的所有內容(除了基本數字類型,如intdouble等)都是Objects。 第二個是第一個的簡寫,就像C具有類似的堆棧分配整數數組的簡寫一樣。

以下兩個代碼片段在編譯級別中是等於的。 我寫了一個Demo類:

public class NewArray {
    public static void main(String[] args) {
        long results[] = new long[3];
    }
}

public class NewArray {
    public static void main(String[] args) {
        long results[] = {0,0,0};
    }
}

'javap -c NewArray'的輸出完全相同:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_3
   1:   newarray long
   3:   astore_1
   4:   return

}

長期結果[] = new long [] {1,2,3}; 結果很長[] = {1,2,3}; 也完全一樣。

所以,雖然有時候你沒有使用新的關鍵詞,但編譯會認為它們是平等的。

'new'關鍵字創建一個數組。 現在,根據數組的數據類型,它內部的值會有所不同。 如果將數組聲明為整數並使用'new'關鍵字,那么它將包含值0,除非您更改其中的值。 使用String,它將包含值'null'。 在每一個空間。

在這兩種情況下,您都會創建一個對

在第一個版本中:

long results[] = new long[3];
results[0] = 1;
results[1] = 2;
results[2] = 3;

你在第一行說數組大小是3.然后你把值放入數組。

在第二個版本:

long results[] = {1, 2, 3};

您創建相同的數組並在同一行中初始化它。 Java計算,你給了3個參數並在沒有你幫助的情況下使new long[3] :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM