4

Java noobの質問:

次のC配列と初期化コードについて考えてみます。

struct {
  int x;
  int y;
} point_t;

point_t points[1000];

簡単。これが作成され、ロード時にメモリが割り当てられます。

ここで、Javaでも同様のことを考えてみましょう。

public class point_t
{
   public int x;
   public int y;
}

point_t points[] = new point_t[1000];
// Without this loop, java will crash when you run this
for (int i=0; i<1000; i++)
{
   points[i] = new point_t;
}
points[0].x = 10;  // Crash would occur here without above loop
points[1].x = 10;

当初、私のJavaプログラムはnullポインター逆参照でクラッシュしていました。問題は、C ++から来て、1000個のpoint_tオブジェクトを作成する必要があることに気づかなかったことです。コメントだけですが、これは非常識なようです。アレイのサイズが100万または10億だったとします。実行時に空のエントリを使用してこの配列を「作成」するには、文字通り数秒かかります。C ++では、すべてロード時に発生します。C ++配列のセルに何が含まれるかを常に知っているとは限りませんが、私が使用している組み込みシステムでは、メモリがゼロに自動初期化されて機能することがよくあります。

では、オブジェクトの配列がある場合に、Javaで配列を作成し、メモリを割り当てるための、より簡単で、より速く、より効率的な方法はありますか?または、上記のコードで何か間違ったことをしていますか?

4

4 に答える 4

7

あなたはC++のバックグラウンドから来ているので、これは役立つかもしれません。Javaでは、あなたが書くとき

point_t points[] = new point_t[1000];

これは、C++での書き込みに似ています。

point_t* points[] = new point_t*[1000];

つまり、Javaでは、配列を作成するときに、C ++でポイントポインタの配列を作成した場合と同じように、ポイントオブジェクトの配列ではなく、ポイント参照の配列を作成します。

Javaは管理された(ガベージコレクションされた)言語です。これは、Javaプログラマーが期待することです。

質問の2番目の部分については、オブジェクト自体をどのように作成するか、あなたが行ったことは問題ありません。ループ内に1000ポイントのオブジェクトを作成し、それらをロードします。より短いコードが必要な場合は、この作業を行うための優れたメソッドを作成できます。:)

このような便利なファクトリメソッドを持つ可能性のある他のコレクションライブラリを調べることもできます。

于 2012-06-16T01:25:27.530 に答える
4

書き込み

point_t[] points = new point_t[ 1000 ];

point_t オブジェクトへの 1000 の参照を割り当てています。(C の用語では、その型の構造体へのポインターを割り当てています。)

そのループ

for (int i=0; i<1000; i++)
{
    points[i] = new point_t;
}

新しい point_t オブジェクトを割り当て、それへの参照 (ポインター) を配列に入れます。それを行うまで、配列は null にすぎず、おそらく null 例外が発生していました。

于 2012-06-16T01:26:33.577 に答える
2

point_tこれはインスタンスの配列ではありません。それらはヒープに住んでいます。

実際point_tには、ヒープ上のインスタンスへの参照の配列です。

参照値に割り当てられることによって (たとえば、new を呼び出すことによって) 初期化されていない参照は、null に設定されます。

配列以外の参照型にも当てはまります。

public class Person {
    private String name; // not initialized; that means it's null
    public Person() {} // oops; constructor should have initialized name, but now it's null
    public String getName() { return name; } // returns null unless you set it properly
    public void setName(String newName) { this.name = newName; }
}
于 2012-06-16T01:31:22.047 に答える
1

Flyweightパターンを使用して、 異なるオブジェクト間で同じデータを共有し、本当に必要になるまでポイントオブジェクトの作成を延期することができます。

于 2012-06-16T02:55:51.397 に答える