16

私はJavaチュートリアルをオンラインでフォローしていて、言語を学ぼうとしています。配列を使用するための2つのセマンティクスの間でバウンスしています。

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

と:

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

チュートリアルでは、なぜ2つの間を行ったり来たりするのかについては実際には触れられていなかったので、このトピックについて少し検索しました。私の現在の理解では、newオペレーターは「longの配列」タイプのオブジェクトを作成しています。私が理解していないのは、なぜそれが欲しいのか、そしてそれの影響は何ですか?

  • 「配列オブジェクト」でない限り、配列で機能しない特定の「配列」固有のメソッドはありますか?
  • 通常の配列でできる「配列オブジェクト」ではできないことはありますか?
  • Java VMは、new通常は実行する必要がない、オペレーターで初期化されたオブジェクトのクリーンアップを実行する必要がありますか?

私はC出身なので、Javaの用語はここでは正しくない可能性があります。理解できないことがあれば、説明を求めてください。

4

9 に答える 9

13

Javaでは、すべての配列とオブジェクトがヒープに割り当てられるため、ある意味で、すべての配列は「配列オブジェクト」です。Javaのスタックに割り当てられるのは、オブジェクト参照とプリミティブだけです。それ以外はすべて、宣言に使用する構文に関係なく、配列を含め、ヒープで定義および割り当てられるオブジェクトです。(2つの例は、最終結果では同等です。それぞれが実際に割り当てられ、割り当てられる方法の詳細については、 JLS§10.3とそのリンクされたセクションを参照してください。)

これは、スタックとヒープの割り当てを明示的に制御できるC /C++とは対照的です。

短期間のオブジェクトの割り当て/割り当て解除に関しては、Javaは非常に高速であることに注意してください。世代ベースのガベージコレクターがあるため、非常に効率的です。だからあなたの質問に答えるために:

「配列オブジェクト」でない限り、配列で機能しない特定の「配列」固有のメソッドはありますか?通常の配列でできる「配列オブジェクト」ではできないことはありますか?

オブジェクトではない配列のようなものはないので、ありません。ただし、プリミティブ配列では機能しないメソッドがあります。をとるメソッドは、最初にそれをに変換せずにObject[]を受け入れません。これは、Java5以降でのオートボクシングの実装の詳細によるものです。long[]Long[]

Java VMは、new通常は実行する必要がない、オペレーターで初期化されたオブジェクトのクリーンアップを実行する必要がありますか?

割り当てられたnewものはすべて最終的にガベージコレクションされる必要があるので、通常は行わないことを行うという点ではどうでしょうか。いいえ。ただし、C / C ++では、malloc/を使用して配列を割り当てると、 /newも必要になることに注意してください。これは、配列を再利用するため、Javaでは必要ありませんfreedelete []

long[]がメソッドで宣言されていて、それをメソッド外の参照に格納しない場合は、メソッド呼び出しの最後にガベージコレクションのマークが自動的に付けられることに注意してください。delete []ガベージコレクタは、必要になるまでそのスペースを再利用するのを待ちますが、 (またはdeleteオブジェクトのデストラクタ)を介して自分で再利用する必要はありません。

編集:約束されたいくつかの参照:

于 2012-12-18T05:01:54.643 に答える
7

Javaのnewキーワードは、新しいオブジェクトを作成します。この場合、オブジェクトである配列...を作成しています。

これらの2つの形式は同等です。2つ目は、1つ目の便利な省略形です。糖衣構文です。

「配列オブジェクト」でない限り、配列で機能しない特定の「配列」固有のメソッドはありますか?

すべての配列はオブジェクトです。限目。

通常の配列でできる「配列オブジェクト」ではできないことはありますか?

上記を参照。

Java VMは、通常は実行する必要がない、new演算子で初期化されたオブジェクトのクリーンアップを実行する必要がありますか?

いいえ。JVMに関する限り、さまざまな方法で作成されたオブジェクトに違いはありません。

于 2012-12-18T05:00:41.977 に答える
5

この2つは、作成されたアレイの動作に関しては同じです。すべての配列は技術的にはJavaのオブジェクトです。これらは、それらを初期化する2つの異なる方法にすぎません。また、次のように2つを組み合わせることができます。

long[] results = new long[]{1,2,3};
于 2012-12-18T05:01:01.203 に答える
3

どちらも同じです。2番目のオプションは、配列オブジェクトの暗黙的な作成を行うことです。これは、ユーザーの便宜のためだけのものです。

于 2012-12-18T05:00:53.153 に答える
3

からJLS#Chapter 10. Arrays

Javaプログラミング言語では、配列はオブジェクト(§4.3.1)であり、動的に作成され、タイプObject(§4.3.2)の変数に割り当てることができます。クラスObjectのすべてのメソッドは、配列で呼び出すことができます。

から10.3. Array Creation

配列は、配列作成式(§15.10)または配列初期化子(§10.6)によって作成されます。

から15.10. Array Creation Expressions

配列作成式は、要素がPrimitiveTypeまたはで指定されたタイプの新しい配列であるオブジェクトを作成しますClassOrInterfaceType

から10.6. Array Initializers

配列初期化子は、宣言(§8.3、§9.3、§14.4)で指定するか、配列作成式(§15.10)の一部として指定して、配列を作成し、いくつかの初期値を提供することができます。

どちらも配列を初期化します。違いは、2番目のものがいくつかの値で初期化することです。

于 2012-12-18T05:01:33.550 に答える
1

あなたが示した2つの作成方法は同等です。どちらも「配列オブジェクト」です。Javaのすべて(、、などの基本的な数値型を除く)はオブジェクトであることを忘れないでintくださいdouble。Cがスタック割り当て整数配列の同様の省略形を持っているのと同じように、2番目は最初の省略形です。

于 2012-12-18T05:01:34.703 に答える
1

次の2つのコードスニペットは、コンパイルレベルが同じです。私は次のようなデモクラスを作成します。

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-cNewArray'の出力はまったく同じです。

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

}

long results [] = new long [] {1,2,3}; そして長い結果[]={1,2,3}; まったく同じです。

したがって、新しいキーワードを使用していない場合もありますが、コンパイルではそれらは同等と見なされます。

于 2012-12-18T05:39:48.673 に答える
1

'new'キーワードは、配列を作成します。現在、データのタイプに応じて、その中の値に対する配列は異なります。配列を整数として宣言し、「new」キーワードを使用すると、内部の値を変更しない限り、値0が含まれます。文字列を使用すると、値'null'が含まれます。すべての単一のスペースで。

于 2016-11-14T14:30:36.640 に答える
0

どちらの場合も、オブジェクトを作成します。

最初のバージョンでは:

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

最初の行で、配列のサイズは3であると言います。次に、配列に値を入力します。

2番目のバージョン:

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

同じ配列を作成し、同じ行で初期化します。Javaは、あなたが3つの引数を与え、new long[3]あなたの助けなしにそれを作成することを計算します:)

于 2012-12-19T20:33:21.420 に答える