Dizinin length özelliği nerede tanımlanır?


263

Biz uzunluğunu belirleyebilir ArrayList<E>kamu yöntemiyle size()gibi

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

Benzer şekilde özelliği Arraykullanarak bir nesnenin uzunluğunu belirleyebilirizlength

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

Oysa size()metodu ArrayListiçinde tanımlandığı ArrayListsınıfı, burada bu lengthmalı Arraytanımlandığı?


Soru organizasyonu açısından, sorunuzu "Array'ın length özelliği nerede tanımlanır?" yayınınızın yeni başlayanların eğitimi gibi görünmesini önlemek için tüm açıklamalardan önce.
NoName

Yanıtlar:


250

Diziler java'da özel nesnelerdir, adında basit bir özniteliği lengthvardır final.

Bir dizinin "sınıf tanımı" yoktur (herhangi bir .class dosyasında bulamazsınız), bunlar dilin kendisinin bir parçasıdır.

10.7. Dizi Üyeleri

Dizi türünün üyeleri aşağıdakilerin tümüdür:

  • public finalAlan lengthdizisi bileşenlerinin sayısını içerir. lengthpozitif veya sıfır olabilir.
  • publicYöntem clonesınıfta aynı adlı yöntemini geçersiz kılar Objectve atar hiçbir ayrıcalık kontrol etti. cloneDizi türü yönteminin dönüş türü ' T[]dir T[].

    Çok boyutlu bir dizinin bir klonu sığdır, yani sadece tek bir yeni dizi oluşturur. Alt diziler paylaşılır.

  • Tüm üyeler sınıftan miras aldı Object; Objectmiras alınmayan tek yöntem onun cloneyöntemidir.

Kaynaklar:


84
Ayrıca ArrayList.size(), dizide gerçekte depolanan nesne sayısını sağlarken myArray.length( []) "kapasite" sağlar. Yani, eğer myArray = new int[10];, 10 değerini döndürür. Diziye koyduğunuz nesne sayısı değildir.
wmorrison365

1
@Colin Dizi nesneleri nasıl bu kadar özel yani tasarımcıların neden özel hale getirmeleri gerekiyor ve neden bir dizinin sınıf dosyasını vermiyorsunuz?
Vikas Verma

5
@VikasVerma Diziler neden nesneler gibi değil? Tarih yüzünden. Java tasarlanırken, söz dizimi ve stilde C'ye benzemediğinde, dil inovasyonu girişimlerinin çoğu başarısız oldu. Böylece C ++, Objective-C ve Java o dönemde belirsizliğin önünden kaçan birkaç dil arasındaydı. Java bilinçli olarak günün ana akım programcılarına tanıdık gelen kıvırcık parantezleri, ilkelleri ve düz dizileri içerecek şekilde tasarlanmıştır . James Gosling ve diğer Sun milletleriyle röportajları görün. Bazı insanlar saf OOP için Koleksiyonlara sadık kalır ve düz dizilerden kaçınır.
Basil Bourque

1
@VikasVerma, bir noktada, java alt düzey teknoloji üzerine inşa edilmelidir. Java yoksa java ile yapılamaz. Java'nın geri kalanı kendi varlığı için bağlam olması için bazı ilkel derleme oluşturmak için C ++ (veya başka bir şey, ancak bu durumda C ++) kullanmanız gerekir. Sonunda C ++ 'da kodladığınız rock bottom vurmadan her şey için sınıf olamaz. Java'da tam olarak nasıl bir dizi oluşturursunuz? Bunu kullanamazsanız List, uygulamalarında diziler kullanır.
Alexander Bird

Bunu cevaplamak istiyorsanız olduğu gibi , daha sonra stackoverflow.com/a/50506451/1059372
Eugene

114

Kendi baytkodu talimat, temelde "özel" var: arraylength. Yani bu yöntem:

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

bayt kodunda şöyle derlenir:

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

Bu yüzden normal bir alanmış gibi erişilmez. Gerçekten de, normal bir alanmış gibi almaya çalışırsanız, böyle, başarısız olur:

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

Ne yazık ki, genel bir son alana sahip her dizi türünün JLS açıklaması lengthbiraz yanıltıcı :(


1
Albert Einstein tarafından yapılan bir alıntıyı tam olarak hatırlamıyorum ama söylediği şey "insanlar bir şeyi çok iyi anlıyor, sadece işleri çok daha basit bir şekilde açıklayabilir" Sana çok
yakıştığını

@Jon Skeet Dizi nesnesi nasıl özel yani tasarımcıların bunu neden özel hale getirmeleri gerekiyor ve neden bir dizinin sınıf dosyasını sağlamıyorum?
Vikas Verma

2
@VikasVerma: Bir dizi nesnesinin boyutunu düşünün. Diğer tüm türler sabit bir boyuta sahiptir - her örnek aynı boyuttadır, ancak diziler uzunluklarına göre değişir. Bu sadece bir örnek. Özel bir şey kullanmadan aynı sonuçları elde edebileceğinizi düşünüyorsanız, bir dizi sınıfının alanlarının nasıl görüneceğini düşünüyorsunuz? int[]Jenerik ilkel tiplere uygulanmadığında nasıl temsil edersiniz ? Sen (Ve halt jenerik. Zaten uzun zamandır yoktu) olabilir tüm koleksiyonları için bağlı listeler kullanarak diziler olmadan kurtulmak, ancak verimlilik için çok kötü olur.
Jon Skeet

@JonSkeet Peki StringBuffer sınıf türü hakkında da sabit boyutu var? Evet gerçekten jenerik ilaçları düşünüyordum ama bunun için teşekkür etmeden önce dikkat çekiyorsun.
Vikas Verma

@VikasVerma: StringBufferSınıfın kendisi, evet - çünkü bir referansı tutar char[](ya da en azından yaptı; hala yapılıp yapılmadığını bilmiyorum). Bu nedenle a StringBuilder, daha fazla bellekten sorumlu olsa da , anlık boyutu ve düzeni sabittir.
Jon Skeet

18

Java dili belirtiminde tanımlanmıştır :

Dizi türünün üyeleri aşağıdakilerin tümüdür:

  • public finalAlan lengthdizisi bileşenlerinin sayısını içerir. lengthpozitif veya sıfır olabilir.

Sınırsız sayıda dizi türü olduğundan (her sınıf için karşılık gelen bir dizi türü vardır ve daha sonra çok boyutlu diziler vardır), bunlar bir sınıf dosyasına uygulanamaz; JVM bunu anında yapmak zorundadır.


15

Bu soruya doğrudan bir cevap olmasa da, .lengthvs .size()argümanına bir ektir . Bu soru ile ilgili bir şey araştırıyordum, bu yüzden karşı karşıya geldiğimde burada tanımların tanımlandığını fark ettim

Dizinin bileşen sayısını içeren genel son alan uzunluğu .

"tam olarak" doğru değil.

Alan uzunluğu , dizide mevcut olan bileşenlerin sayısını değil, bir bileşen koymak için kullanılabilir yerlerin sayısını içerir. Bu nedenle, o belleğin ne kadarının doldurulduğunu değil, o diziye ayrılan toplam kullanılabilir belleği temsil eder.

Dizi Bellek Ayırma

Misal:

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

Çıktı:

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

Ancak, .size()özelliği ArrayList, listedeki öğelerin sayısını verir:

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

Çıktı:

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

1
Doğru, çünkü tüm elemanlar sıfırlandı. Diziler "boş" olamaz
Guido

Ben de öyle dedim. "Tam olarak" doğru değil. Diziye hiçbir şey eklenmemesine rağmen uzunluğu 5'tir. Bu nedenle, dizideki öğelerin sayısını "tam olarak" içermez. Yorumunuz sadece cevabımın bir yanı, yanlış yapmak için bir neden değil.
nem035

Eğer nullnull ve null olmayan elemanlar arasında ayrım yapmaya çalışırsanız "yanlış" olabilir . Fakat ayrım işe yaramıyor. Sonuçta, size()a (diyelim) a değerleri de Listiçerebilir null.
Stephen C

Evet, aslında benim amacım sizedinamik davranıyor, lengthstatik bir özellik iken ... bir dizide kalan doldurulmamış alanın " Değerler Değil " olarak başlatılması (türe bağlı olarak) bu nokta ile gerçekten çelişmiyor.
nem035

5

dizinin bileşen sayısını içeren genel son alanıdır (uzunluk pozitif veya sıfır olabilir)

Böylece bir dizi, aşağıdaki sınıfla aynı ortak alanlara ve yöntemlere sahiptir:

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

daha fazla bilgi için

10.7 Dizi Üyeleri

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


0

Olduğu gibi yanıtlamak için , dizinin bu length özelliği nerede tanımlanır ? Özel birObject header .

JOL ile görülmesi kolay

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

Bu çıktıdaki satırlardan biri şöyle olacak:

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

Genellikle nesnelerin iki üstbilgisi (işaret ve klass) vardır, diziler her zaman 4 bytesuzunluğu kadar sizeolan bir tane daha vardır int.


-1

Anahtar kelime uzunluğu, tanımlı bir veri gibi davranır. Bir dizide kullanırken, bunu bir dizideki kaç öğeye erişmek için kullanabiliriz. String [] ile ilgili olarak, String sınıfında tanımlanan length () yöntemini çağırabiliriz. ArrayList ile ilgili olarak, ArrayList'te tanımlanan size () yöntemini kullanabiliriz. ArrayList <> (kapasite) ile bir dizi listesi oluştururken, öğe olmadığından bu dizi listesinin başlangıç ​​boyutunun () sıfır olduğunu unutmayın.

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.