配列の長さプロパティはどこで定義されていますか?


263

次のようにArrayList<E>、パブリックメソッドを使用しての長さを決定できます。size()

ArrayList<Integer> arr = new ArrayList(10);
int size = arr.size();

同様にArraylengthプロパティを使用してオブジェクトの長さを決定できます

String[] str = new String[10];
int size =  str.length;

size()メソッドはクラスArrayList内で定義されていますArrayListが、このlengthプロパティのArray定義はどこにありますか?


質問の整理に関しては、「配列の長さプロパティはどこに定義されているのですか?」あなたの投稿が初心者のチュートリアルのように聞こえるのを防ぐためのすべての説明の前に。
NoName 2017

回答:


250

配列はJavaの特別なオブジェクトであり、であるという名前の単純な属性がlengthありますfinal

配列の「クラス定義」はありません(.classファイルでは見つかりません)。それらは言語自体の一部です。

10.7。配列メンバー

配列型のメンバーは次のすべてです。

  • public finalフィールドlengthアレイの構成要素の数を含みます。length正またはゼロの場合があります。
  • publicメソッドcloneクラスの同名のメソッドをオーバーライドし、Objectそして何のチェック例外をスローしません。clone配列型のメソッドの戻り値の型T[]T[]です。

    多次元配列のクローンは浅いです。つまり、単一の新しい配列のみを作成します。サブアレイは共有されます。

  • クラスから継承されたすべてのメンバーObjectObject継承されない唯一のメソッドは、そのcloneメソッドです。

リソース:


84
また、ArrayList.size()は実際に配列に格納されているオブジェクトの数を提供しますが、myArray.length[])は「容量」を提供します。つまり、の場合、myArray = new int[10];10を返します。これは、配列に入れたオブジェクトの数ではありません。
wmorrison365

1
@Colin配列オブジェクトがどのように特別であるか私はなぜデザイナーがそれを特別にする必要があるのか​​、そしてなぜ配列のクラスファイルを提供しないのか?
Vikas Verma

5
@VikasVermaなぜ配列はオブジェクトではないのですか?歴史のため。Javaが設計されたとき、構文とスタイルがCに似ていない場合、言語革新のほとんどの試みは失敗しました。したがって、C ++、Objective-C、およびJavaは、その時代のあいまいさを回避する数少ない言語の1つでした。Javaは、中括弧、プリミティブ、プレーンアレイを含むように意識的に設計されており、当時の主流のプログラマーには馴染み深いように見えます。James Goslingや他のSunの人々へのインタビューをご覧ください。一部の人々は純粋なOOPのコレクションを使い、単純な配列を避けます。
バジルブルク2015

1
@VikasVerma、ある時点で、Javaは下位レベルのテクノロジー上に構築する必要があります。javaが存在しない場合は、javaでビルドできません。残りのJavaが独自の存在のコンテキストを持つために、いくつかのプリミティブコンパイルをビルドするには、C ++(または何か他のものですが、この場合はC ++)を使用する必要があります。C ++でコーディングする場合、最終的にロックボトムに到達しない限り、すべてのクラスを作成することはできません。どのように正確にJavaで配列を構築しますか?List実装で配列を使用するため、aを使用できない場合。
Alexander Bird

そのまま回答する場合stackoverflow.com / a / 50506451/1059372
Eugene

114

これは基本的に「特別」で、独自のバイトコード命令がありますarraylength。したがって、このメソッド:

public static void main(String[] args) {
    int x = args.length;
}

このようにバイトコードにコンパイルされます:

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   arraylength
   2:   istore_1
   3:   return

そのため、通常のフィールドのようにアクセスされません。実際、次のように通常のフィールドであるかのように取得しようとすると、失敗します。

// Fails...
Field field = args.getClass().getField("length");
System.out.println(field.get(args));

残念ながら、パブリックファイナルフィールドを持つ各配列型のJLS記述は、length誤解を招く:(


1
私は正確にアルバート・アインシュタインの言葉を覚えていないが、何それはのは言う、「人々は非常によく事を理解することは非常に簡単な方法で物事を説明することができ、」私は、それは非常によくあなたにぴったりだと思う:)
JAVA

@Jon Skeet配列オブジェクトはどのように特別なのですか?なぜデザイナーはそれを特別にする必要があり、なぜ配列のクラスファイルを提供しないのですか?
Vikas Verma

2
@VikasVerma:配列オブジェクトのサイズについて考えてください。他のすべてのタイプには固定サイズがあります。すべてのインスタンスは同じサイズですが、配列は長さに基づいて変化します。それはほんの一例です。特別なものを使用しなくても同じ結果が得られると思うなら、配列クラスのフィールドはどのように見えると思いますか?int[]ジェネリックがプリミティブ型に適用されない場合、どのように表現しますか?(そして、とにかく、ジェネリックは長い間存在していませんでした。)すべてのコレクションにリンクリストを使用することにより、配列なしで済むことができます、効率が悪くなります。
Jon Skeet、

@JonSkeetしかし、サイズが固定されているStringBufferクラス型についてはどうですか?はい、確かに私はジェネリック医薬品について考えていましたが、ありがとうと尋ねる前に指摘しました。
Vikas Verma

@VikasVerma:StringBufferクラス自体はそうです、そうです-それはaへの参照を保持しているからですchar[](または少なくともそうでした;私はそれがまだ手に持っているかどうかわかりません)。したがって、a StringBuilderはより多くのメモリを担当しますが、その直接のサイズとレイアウトは固定されます。
Jon Skeet、

18

これは、Java言語仕様で定義されています

配列型のメンバーは次のすべてです。

  • public finalフィールドlengthアレイの構成要素の数を含みます。length正またはゼロの場合があります。

配列型の無限の数があるので(すべてのクラスの対応する配列型があり、その後、それらはクラスファイルに実装することができない多次元配列があります)。JVMはその場で実行する必要があります。


15

これは質問に対する直接の回答ではありませんが、.lengthvs .size()引数への追加です。私はこの質問に関連するものを調査していたので、それに遭遇したとき、ここに提供されている定義に気づきました

配列のコンポーネントの数を含むパブリックの最終フィールド長。

「正確に」正しくない。

フィールド長には、配列内に存在するコンポーネントの数ではなく、コンポーネントを配置できる場所の数が含まれています。したがって、それは、そのアレイに割り当てられた利用可能なメモリの合計を表すものであり、そのメモリのどれだけが満たされているのかではありません。

配列メモリの割り当て

例:

static class StuffClass {
    int stuff;
    StuffClass(int stuff) {
        this.stuff = stuff;
    }
}

public static void main(String[] args) {

    int[] test = new int[5];
    test[0] = 2;
    test[1] = 33;
    System.out.println("Length of int[]:\t" + test.length);

    String[] test2 = new String[5];
    test2[0] = "2";
    test2[1] = "33";    
    System.out.println("Length of String[]:\t" + test2.length);

    StuffClass[] test3 = new StuffClass[5];
    test3[0] = new StuffClass(2);
    test3[1] = new StuffClass(33);
    System.out.println("Length of StuffClass[]:\t" + test3.length);         
}

出力:

Length of int[]:        5
Length of String[]:     5
Length of StuffClass[]: 5

ただし、の.size()プロパティはArrayList、リスト内の要素の数を示します。

ArrayList<Integer> intsList = new ArrayList<Integer>();
System.out.println("List size:\t" + intsList.size());
intsList.add(2);
System.out.println("List size:\t" + intsList.size());
intsList.add(33);
System.out.println("List size:\t" + intsList.size());

出力:

List size:  0
List size:  1
List size:  2

1
すべての要素がゼロに初期化されているので、それは正しいです。配列を「空」にすることはできません
グイド

まあそれはまさに私が言ったことです。「正確に」正しくはありません。配列に何も追加されていなくても、長さは5のままです。したがって、配列の要素の数が「正確に」含まれていません。あなたのコメントは私の回答への単なる追加であり、それを不正確にする理由ではありません。
nem035

nullnull以外の要素を区別しようとすると、「正しくない」可能性があります。しかし、その区別は機能しません。結局のところ、size()(たとえば)aにListnull値も含まれる場合があります。
スティーブンC

うん、本質的に私の点は静的なプロパティsizeでありながら動的に動作するということでしたlength...配列内の残りの塗りつぶされていないスペースが(値に応じて)「値以外」に初期化されるという事実は実際にはこの点と矛盾しません。
nem035

5

配列のコンポーネントの数を含むパブリックファイナルフィールド(長さは正またはゼロの場合があります)

したがって、配列には次のクラスと同じパブリックフィールドとメソッドがあります。

class A implements Cloneable, java.io.Serializable {
    public final int length = X;
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.getMessage());
        }
    }
}

詳細は

10.7配列メンバー

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html


0

そのまま答えるために、配列のこの長さプロパティはどこで定義されていますか?特別にObject header

経由して見やすいJOL

 int [] ints = new int[23];
 System.out.println(ClassLayout.parseInstance(ints).toPrintable());

この出力の行の1つは次のようになります。

OFFSET  SIZE      TYPE DESCRIPTION
16       4        (object header)   17 00 00 00 (00010111 00000000 00000000 00000000) (23)

通常、オブジェクトには2つのヘッダー(マークとクラス)があり、配列には4 bytesと同様に常に長さを占めるもう1つのヘッダーsizeがありintます。


-1

キーワードの長さは、定義されたデータフィールドのように機能します。配列で使用する場合、配列内の要素数にアクセスするために使用できます。String []に関しては、Stringクラスで定義されたlength()メソッドを呼び出すことができます。ArrayListについては、ArrayListで定義されているsize()メソッドを使用できます。ArrayList <>(capacity)で配列リストを作成する場合、要素がないため、この配列リストの初期size()はゼロであることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.