Bir bildirimde değilken dizi başlatma sözdizimi


141

Yazabilirim:

AClass[] array = {object1, object2}

Ayrıca şunu da yazabilirim:

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

ama yazamıyorum:

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

Bu neden Java tarafından engellendi?

Nasıl çalışacağını biliyorum, ama zaman zaman daha basit olurdu.

Örneğin:

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

Java'da dizilerle oynamayı öğrendiğimden beri beni rahatsız eden bu basit soru.


Metin biçimi için üzgünüm, ancak Çin'de herhangi bir nedenle metin düzeni düğmeleri görünmüyor: S
Jason Rogers

kod için 4 boşluk veya daha fazla girintili olduğundan emin olun.
Mat

diğer sorun yapıştırdığınız kodda TAB karakterleri olması. Bu biçimlendirmeyi bozar.
Stephen C

Oki teşekkürler, eclipse girintideki sekmeleri kullanır, bu yüzden yapıştırdığımda kopyaları karıştırır. düzenleme için teşekkürler
Jason Rogers

Eclipse girinti için SEKME karakterlerini kullanmayacak şekilde yeniden yapılandırılabilir ve yapılandırılmalıdır. Lütfen bunu bahane olarak kullanmayın.
Stephen C

Yanıtlar:


137

Bu neden Java tarafından engellendi?

Java tasarımcılarına sormanız gerekir. Kısıtlamanın bazı ince gramer nedenleri olabilir. Bazı dizi oluşturma / başlatma yapılarının Java 1.0'da olmadığını ve (IIRC) Java 1.1'de eklendiğini unutmayın.

Ama "neden" önemsizdir ... kısıtlama oradadır ve onunla yaşamak zorundasınız.

Nasıl çalışacağını biliyorum, ama zaman zaman daha basit olurdu.

Bunu yazabilirsiniz:

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

9
yeni bildirim olmadan, bir ifade bloğu ve dizi başlatıcısı arasında bir fark olmayacaktır (javascript'te olduğu gibi, yanıltıcı olabilir}
bestsss

10
Bu olur kafa karıştırıcı ... ve ayrıştırmak zor. {o1()}Geçerli bir ifade olup {o1();}olmadığını ve geçerli bir ifade bloğu olup olmadığını düşünün . Ayrıştırıcı '}' veya ';' önce iki vakayı ayırt edebiliyordu. Dilbilgisi sorunu hiç de ince değildir !!
Stephen C

19

Neden soruyu cevaplamaya çalışacağım: Java dizisi ArrayList gibi daha dinamik sınıflara kıyasla çok basit ve basit. Java, bildirim zamanında dizi için ne kadar bellek ayrılması gerektiğini bilmek ister. Bir ArrayList çok daha dinamiktir ve boyutu zamanla değişebilir.

Dizinizi iki uzunlukla başlatırsanız ve daha sonra üç uzunluğa ihtiyacınız olduğu ortaya çıkarsa, sahip olduklarınızı atmanız ve tamamen yeni bir dizi oluşturmanız gerekir. Bu nedenle 'yeni' anahtar kelime.

İlk iki örneğinizde, beyan zamanında ne kadar bellek ayıracağını söylersiniz. Üçüncü örneğinizde, dizi adı hiçbir şeye işaretçi olmaz ve bu nedenle başlatıldığında doğru miktarda bellek ayırmak için açıkça yeni bir dizi oluşturmanız gerekir.

İlk örnek bunu söyleyebilirim (ve birisi daha iyisini bilirse, lütfen beni düzeltin)

AClass[] array = {object1, object2}

aslında şu anlama gelir

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

ancak Java tasarımcılarının yaptığı şey, diziyi bildirim zamanında oluşturursanız yazmak için daha hızlı bir yol yapmaktı.

Önerilen geçici çözümler iyidir. Çalışma zamanında zaman veya bellek kullanımı kritikse, dizileri kullanın. Kritik değilse ve anlaşılması ve üzerinde çalışılması daha kolay olan bir kod istiyorsanız ArrayList kullanın.


2
Bu, belirttiğiniz gibi bir kısayoldur, Oracle'dan Alıntı: "Alternatif olarak, bir dizi oluşturmak ve başlatmak için kısayol sözdizimini kullanabilirsiniz" . Bunun nedeni, bir dizinin bir noktada yeni kullanılarak bellekte bir miktar yer alması olabilir . Kısayolda yeni örtük, ancak kısayol yalnızca bildirimde geçerlidir. Başka yerlerde, izin verilen bir kısayol yoktur ve yeni zorunludur.
dakika

3
Üzgünüm, ama "neden" sorusunu cevaplama girişiminiz su tutmuyor. Derleyici dizi arasındaki ifadeleri sayarak olması gerekiyordu ne kadar büyük atlatmanın mümkün olacağını {ve }bu izin verilir başlatıcı formları için yaptığı gibi ....
Stephen C

8

Neden kısmına cevap veremem.

Ancak dinamik bir şey istiyorsanız neden Collection ArrayList'i düşünmüyorsunuz?

ArrrayList herhangi bir Nesne türünde olabilir.

Ve eğer bir zorlama olarak dizi olarak istiyorsanız, üzerinde toArray () yöntemini kullanabilirsiniz.

Örneğin:

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

Umarım bu size yardımcı olabilir.


2
Dizinin dönüş türünün String [] biçimine dökülmesine gerek yoktur. Sözleşmeyle, döndürülen Dizi belirtilen diziyle aynı türdedir. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal

4

Bu korkunç new AClass[] { ... }sözdizimini sevmeyenler için biraz şeker:

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

Bu küçük işlevi istediğiniz gibi kullanın:

AClass[] array;
...
array = c(object1, object2);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.