Di mana properti panjang array didefinisikan?

263

Kita dapat menentukan panjang ArrayList<E>menggunakan metode publiknya size(), seperti

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

Demikian pula kita dapat menentukan panjang suatu Arrayobjek menggunakan lengthproperti

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

Sedangkan size()metode ArrayListdidefinisikan di dalam ArrayListkelas, di mana lengthproperti ini Arraydidefinisikan?

ORANG BODOH
sumber
Dalam hal organisasi pertanyaan, saya sarankan untuk mengajukan pertanyaan Anda "di mana properti panjang Array didefinisikan?" sebelum semua penjelasan untuk mencegah posting Anda terdengar seperti tutorial pemula.
NoName

Jawaban:

250

Array adalah objek khusus di Jawa, mereka memiliki atribut sederhana bernama lengthyang final.

Tidak ada "definisi kelas" dari sebuah array (Anda tidak dapat menemukannya dalam file .class apa pun), mereka adalah bagian dari bahasa itu sendiri.

10.7. Anggota Array

Anggota tipe array adalah semua hal berikut ini:

  • The public finallapangan length, yang berisi jumlah komponen dari array. lengthmungkin positif atau nol.
  • The publicmetode clone, yang menggantikan metode dengan nama yang sama di kelas Objectdan melempar ada pengecualian diperiksa. Jenis pengembalian clonemetode tipe array T[]adalah T[].

    Klon dari array multidimensi adalah dangkal, yang artinya hanya menciptakan satu array baru. Subarrays dibagikan.

  • Semua anggota diwarisi dari kelas Object; satu-satunya metode Objectyang tidak diwariskan adalah clonemetodenya.

Sumber:

Colin Hebert
sumber
84
Perhatikan juga bahwa ArrayList.size()menyediakan jumlah objek yang sebenarnya disimpan dalam array sedangkan myArray.length( []) menyediakan "kapasitas". Artinya, jika untuk myArray = new int[10];, ia mengembalikan 10. Ini bukan jumlah objek yang Anda masukkan ke dalam array.
wmorrison365
1
@Colin Bagaimana objek array sangat istimewa Maksudku, mengapa desainer perlu membuatnya istimewa dan mengapa tidak menyediakan file kelas dari array?
Vikas Verma
5
@VikasVerma Mengapa array tidak seperti objek? Karena sejarah. Ketika Java dirancang, sebagian besar upaya inovasi bahasa gagal ketika tidak mirip dengan C dalam sintaks dan gaya. Jadi C ++, Objective-C, dan Java adalah beberapa di antara beberapa bahasa untuk menghindari ketidakjelasan selama era itu. Java secara sadar dirancang untuk menyertakan kurung kurawal, primitif , dan susunan sederhana agar tampak familier bagi programmer arus utama saat itu. Lihat wawancara dengan James Gosling dan orang Sun lainnya. Beberapa orang tetap menggunakan Koleksi untuk OOP murni, dan menghindari array sederhana.
Basil Bourque
1
@VikasVerma, di beberapa titik, java harus dibangun di atas teknologi tingkat yang lebih rendah. Jika java tidak ada, Anda tidak dapat membangunnya dengan java. Anda harus menggunakan C ++ (atau sesuatu yang lain, tetapi C ++ dalam kasus ini) untuk membangun beberapa kompilasi primitif untuk seluruh java agar memiliki konteks untuk keberadaannya sendiri. Anda tidak dapat memiliki kelas untuk semuanya tanpa akhirnya mencapai titik terendah di mana Anda mengkodekannya dalam C ++. Bagaimana tepatnya Anda membangun array di java? Jika Anda tidak dapat menggunakan Listkarena itu menggunakan array dalam implementasinya.
Alexander Bird
jika Anda ingin menjawabnya apa adanya , maka stackoverflow.com/a/50506451/1059372
Eugene
114

Ini "khusus" pada dasarnya, dengan instruksi bytecode sendiri: arraylength. Jadi metode ini:

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

dikompilasi menjadi bytecode seperti ini:

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

Jadi itu tidak diakses seolah-olah itu adalah bidang normal. Memang, jika Anda mencoba untuk mendapatkannya seolah-olah itu adalah bidang normal, seperti ini, gagal:

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

Sayangnya, deskripsi JLS untuk setiap jenis array yang memiliki bidang akhir publik lengthagak menyesatkan :(

Jon Skeet
sumber
1
Saya tidak ingat persis kutipan oleh Albert Einstein tetapi apa yang dikatakannya adalah "orang-orang memahami sesuatu dengan sangat baik hanya dapat menjelaskan hal-hal dengan cara yang lebih sederhana" Saya pikir itu sangat cocok untuk Anda :)
JAVA
@ Jon Skeet Bagaimana objek array khusus Maksudku, mengapa desainer perlu membuatnya istimewa dan mengapa tidak menyediakan file kelas array?
Vikas Verma
2
@VikasVerma: Pikirkan tentang ukuran objek array. Semua tipe lainnya memiliki ukuran yang tetap - setiap instance memiliki ukuran yang sama, sedangkan array bervariasi berdasarkan panjangnya. Itu hanya satu contoh. Jika Anda pikir Anda bisa mencapai hasil yang sama tanpa menggunakan sesuatu yang spesial, menurut Anda seperti apa bidang dari kelas array? Bagaimana Anda mewakili int[]ketika obat generik tidak berlaku untuk tipe primitif? (Dan, sih, obat generik tidak ada untuk waktu yang lama.) Anda bisa pergi tanpa array dengan menggunakan daftar tertaut untuk semua koleksi, tetapi itu akan sangat buruk untuk efisiensi.
Jon Skeet
@ JonSkeet Tapi bagaimana dengan tipe kelas StringBuffer itu juga memiliki ukuran tetap? Ya memang saya sedang memikirkan obat generik tetapi Anda menunjukkan sebelum saya meminta Terima kasih untuk itu.
Vikas Verma
@VikasVerma: StringBufferKelas itu sendiri, ya - karena kelas ini memiliki referensi ke char[](atau memang, setidaknya; saya tidak tahu apakah masih ada, begitu saja). Jadi, sementara a StringBuilderbertanggung jawab untuk lebih banyak memori, ukuran dan tata letaknya langsung diperbaiki.
Jon Skeet
18

Ini didefinisikan dalam spesifikasi bahasa Java :

Anggota tipe array adalah semua hal berikut ini:

  • The public finallapangan length, yang berisi jumlah komponen dari array. lengthmungkin positif atau nol.

Karena ada jumlah tipe array yang tidak terbatas (untuk setiap kelas ada tipe array yang sesuai, dan kemudian ada array multidimensi), mereka tidak dapat diimplementasikan dalam file kelas; JVM harus melakukannya dengan cepat.

Michael Borgwardt
sumber
15

Meskipun ini bukan jawaban langsung untuk pertanyaan, ini merupakan tambahan dari argumen .lengthvs. .size()Saya sedang meneliti sesuatu yang berkaitan dengan pertanyaan ini, jadi ketika saya menemukan itu, saya perhatikan bahwa definisi yang diberikan di sini

Panjang bidang akhir publik, yang berisi jumlah komponen array .

tidak "tepat" benar.

Panjang bidang berisi jumlah tempat yang tersedia untuk meletakkan komponen, bukan jumlah komponen yang ada dalam array. Jadi itu mewakili total memori yang tersedia dialokasikan untuk array itu, bukan berapa banyak memori yang diisi.

Alokasi Memori Array

Contoh:

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);         
}

Keluaran:

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

Namun, .size()properti ArrayListtidak memberikan jumlah elemen dalam daftar:

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());

Keluaran:

List size:  0
List size:  1
List size:  2
nem035
sumber
1
Itu benar, karena semua elemen diinisialisasi ke nol. Array tidak boleh "kosong"
Guido
Ya, itulah yang saya katakan. Itu "tidak tepat" benar. Itu masih memiliki panjang 5 meskipun tidak ada yang ditambahkan ke array. Jadi itu tidak "persis" mengandung jumlah elemen dalam array. Komentar Anda hanyalah tambahan untuk jawaban saya, bukan alasan untuk membuatnya salah.
nem035
Ini bisa "salah" jika Anda mencoba membuat perbedaan antara nulldan elemen yang tidak nol. Tetapi perbedaannya tidak berhasil. Bagaimanapun, the size()(katakanlah) a Listdapat menyertakan nullnilai juga.
Stephen C
Yup, intinya poin saya adalah yang sizeberperilaku dinamis, sementara itu lengthadalah properti statis ... fakta bahwa sisa ruang yang tidak terisi dalam sebuah array akan diinisialisasi ke " Nilai Non " (tergantung pada jenisnya) tidak benar-benar bertentangan dengan titik ini.
nem035
5

itu adalah bidang final publik, yang berisi jumlah komponen array (panjangnya bisa positif atau nol)

Dengan demikian, array memiliki bidang dan metode publik yang sama dengan kelas berikut:

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());
        }
    }
}

info lebih lanjut di

10.7 Anggota Array

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

Massimiliano Peluso
sumber
0

Untuk menjawabnya apa adanya, di mana properti panjang array ini didefinisikan ? Secara khusus Object header.

Mudah dilihat melalui JOL

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

Salah satu baris dari output ini adalah:

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

Biasanya Objek memiliki dua header (tanda dan klass), array memiliki satu lagi yang selalu menempati 4 bytespanjangnya, seperti sizesebuah int.

Eugene
sumber
-1

Panjang kata kunci bertindak seperti data yang diajukan didefinisikan. Saat menggunakan dalam sebuah array, kita dapat menggunakannya untuk mengakses berapa banyak elemen dalam sebuah array. Mengenai String [], kita dapat memanggil metode length () yang didefinisikan dalam kelas String. Berkenaan dengan ArrayList, kita dapat menggunakan metode size () yang didefinisikan dalam ArrayList. Perhatikan bahwa saat membuat daftar array dengan ArrayList <> (kapasitas), ukuran awal () dari daftar array ini adalah nol karena tidak ada elemen.

Xiaogang
sumber