Array sintaks inisialisasi saat tidak dalam deklarasi

141

Saya bisa menulis:

AClass[] array = {object1, object2}

Saya juga bisa menulis:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

tapi saya tidak bisa menulis:

AClass[] array;
...
array = {object1, object2};

Mengapa ini diblokir oleh Java?

Saya tahu bagaimana cara mengatasinya, tetapi dari waktu ke waktu akan lebih mudah.

Sebagai contoh:

public void selectedPointsToMove(cpVect coord) {

    if (tab == null) {
        if (arePointsClose(coord, point1, 10)) {
            cpVect[] tempTab = {point1};
            tab = tempTab;
        } else if (arePointsClose(point2, coord, 10)) {
            cpVect[] tempTab = {point2};
            tab = tempTab;
        } else {
            cpVect[] tempTab = {point1,point2};
            tab = tempTab;
        }
    }
}

Pertanyaan sederhana ini yang telah mengganggu saya sejak saya belajar cara bermain dengan array di Jawa.

Jason Rogers
sumber
Maaf tentang format teks tetapi untuk beberapa alasan di Cina tombol tata letak teks tidak muncul: S
Jason Rogers
untuk kode, pastikan indentasi dengan 4 spasi atau lebih.
Mat
masalah lainnya adalah Anda memiliki karakter TAB dalam kode yang Anda tempel. Ini mengacaukan pemformatan.
Stephen C
Oki terima kasih, eclipse menggunakan tab di indentasi jadi ketika saya salin itu mengacaukan semuanya. terima kasih untuk hasil editnya
Jason Rogers
Eclipse dapat dan harus dikonfigurasi ulang untuk tidak menggunakan karakter TAB untuk indentasi. Tolong jangan gunakan itu sebagai alasan.
Stephen C

Jawaban:

137

Mengapa ini diblokir oleh Java?

Anda harus bertanya pada desainer Java. Mungkin ada beberapa alasan tata bahasa yang halus untuk pembatasan ini. Perhatikan bahwa beberapa konstruksi pembuatan / inisialisasi array tidak di Java 1.0, dan (IIRC) ditambahkan di Java 1.1.

Tetapi "mengapa" tidak penting ... pembatasan ada di sana, dan Anda harus hidup dengannya.

Saya tahu bagaimana cara mengatasinya, tetapi dari waktu ke waktu akan lebih mudah.

Anda dapat menulis ini:

AClass[] array;
...
array = new AClass[]{object1, object2};
Stephen C
sumber
9
tanpa deklarasi baru, tidak akan ada perbedaan antara blok pernyataan dan penginisialisasi array (seperti dalam javascript, yang bisa menyesatkan}
bestsss
10
Itu akan membingungkan ... dan sulit diurai. Pertimbangkan apakah {o1()}itu ekspresi yang valid dan {o1();}blok pernyataan yang valid. Parser harus menuju ke '}' atau ';' sebelum dapat membedakan kedua kasus tersebut. Masalah tata bahasanya tidak halus sama sekali !!
Stephen C
19

Saya akan mencoba menjawab pertanyaan mengapa: Java array sangat sederhana dan belum sempurna dibandingkan dengan kelas-kelas seperti ArrayList, yang lebih dinamis. Java ingin tahu pada waktu deklarasi berapa banyak memori yang harus dialokasikan untuk array. ArrayList jauh lebih dinamis dan ukurannya dapat bervariasi dari waktu ke waktu.

Jika Anda menginisialisasi array Anda dengan panjang dua, dan kemudian ternyata Anda membutuhkan panjang tiga, Anda harus membuang apa yang Anda punya, dan membuat array baru. Karenanya kata kunci 'baru'.

Dalam dua contoh pertama Anda, Anda memberi tahu pada waktu deklarasi berapa banyak memori yang dialokasikan. Pada contoh ketiga Anda, nama array menjadi pointer ke nothing, dan karena itu, ketika diinisialisasi, Anda harus secara eksplisit membuat array baru untuk mengalokasikan jumlah memori yang tepat.

Saya akan mengatakan itu (dan jika seseorang lebih tahu, tolong perbaiki saya) contoh pertama

AClass[] array = {object1, object2}

sebenarnya berarti

AClass[] array = new AClass[]{object1, object2};

tetapi apa yang dilakukan oleh desainer Java, adalah membuat cara yang lebih cepat untuk menulisnya jika Anda membuat array pada waktu deklarasi.

Solusi yang disarankan baik. Jika waktu atau penggunaan memori sangat penting saat runtime, gunakan array. Jika tidak kritis, dan Anda menginginkan kode yang lebih mudah dipahami dan digunakan, gunakan ArrayList.

tingkatkan
sumber
2
Ini adalah jalan pintas seperti yang Anda nyatakan, Mengutip Oracle: "Atau, Anda dapat menggunakan sintaks cara pintas untuk membuat dan menginisialisasi array" . Alasannya mungkin array harus diberi ruang dalam memori menggunakan baru di beberapa titik. Baru tersirat dalam pintasan, tetapi pintasan hanya valid dalam deklarasi. Di tempat lain, tidak ada jalan pintas yang diizinkan, dan yang baru wajib.
mnt
3
Maaf, tetapi upaya Anda untuk menjawab pertanyaan "mengapa" tidak membuahkan hasil. Kompiler akan dapat mengetahui seberapa besar array yang diperlukan dengan menghitung ekspresi antara {dan }... seperti halnya untuk form initializer yang diizinkan.
Stephen C
8

Saya tidak bisa menjawab bagian mengapa.

Tetapi jika Anda menginginkan sesuatu yang dinamis, mengapa Anda tidak mempertimbangkan Collection ArrayList.

ArrrayList dapat berupa jenis Obyek apa pun.

Dan jika sebagai keharusan Anda menginginkannya sebagai array, Anda dapat menggunakan metode toArray () di atasnya.

Sebagai contoh:

            ArrayList<String> al = new ArrayList<String>();
            al.add("one");
            al.add("two");
            String[] strArray = (String[]) al.toArray(new String[0]);

Saya harap ini dapat membantu Anda.

Amanpreet
sumber
2
Tidak perlu membuang tipe pengembalian Array ke String []. Dengan kontrak Array yang dikembalikan adalah jenis yang sama dengan array yang ditentukan. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal
4

Bagi Anda, yang tidak menyukai new AClass[] { ... }sintaksis mengerikan ini , inilah beberapa gula:

public AClass[] c(AClass... arr) { return arr; }

Gunakan fungsi kecil ini sesuka Anda:

AClass[] array;
...
array = c(object1, object2);
pengguna123
sumber