length dan length () di Java

88

Mengapa kita memiliki panjang array sebagai atribut array.length, dan untuk String kita punya metode str.length(),?

Apakah ada alasannya?

Nitish Upreti
sumber
3
Telah dibahas sebelumnya di CodeRanch. Simak pembahasannya di sini.
missingfaktor

Jawaban:

98

Izinkan saya menyoroti tiga cara berbeda untuk tujuan yang sama.

length- array ( int[], double[], String[]) - untuk mengetahui panjang array

length()- String Object terkait ( String, StringBuilder, dll) - untuk mengetahui panjang String

size()- Objek Koleksi ( ArrayList,, Setdll) - untuk mengetahui besarnya Koleksi

Sekarang lupakan tentang length()mempertimbangkan adil lengthdan size().

lengthbukanlah sebuah metode, jadi sangat masuk akal bahwa metode ini tidak akan bekerja pada objek. Ini hanya bekerja pada array.
size()namanya mendeskripsikannya dengan lebih baik dan karena ini adalah sebuah metode, ini akan digunakan dalam kasus objek yang bekerja dengan koleksi (kerangka kerja kumpulan) seperti yang saya katakan di atas.

Sekarang datang ke length():
String bukanlah array primitif (jadi kita tidak bisa menggunakan .length) dan juga bukan Collection (jadi kita tidak bisa menggunakan .size()) itu sebabnya kita juga membutuhkan array yang berbeda length()(menjaga perbedaan dan melayani tujuan).

Sebagai jawaban untuk Mengapa?
Menurut saya ini berguna, mudah diingat dan digunakan serta ramah.

Saif
sumber
6
solusi yang luar biasa!
Jeff Hu
27

Sedikit disederhanakan, Anda dapat menganggapnya sebagai array sebagai kasus khusus dan bukan kelas biasa (agak mirip primitif, tetapi tidak). String dan semua koleksinya adalah kelas, oleh karena itu metode untuk mendapatkan ukuran, panjang, atau hal serupa.

Saya kira alasan pada saat desain itu adalah kinerja. Jika mereka membuatnya hari ini, mereka mungkin muncul dengan sesuatu seperti kelas koleksi yang didukung array.

Jika ada yang tertarik, berikut adalah cuplikan kecil kode untuk menggambarkan perbedaan antara keduanya dalam kode yang dihasilkan, pertama sumbernya:

public class LengthTest {
  public static void main(String[] args) {
    int[] array = {12,1,4};
    String string = "Hoo";
    System.out.println(array.length);
    System.out.println(string.length());
  }
}

Memotong cara bagian yang tidak begitu penting dari kode byte, berjalan javap -cpada hasil kelas sebagai berikut untuk dua baris terakhir:

20: getstatic   #3; //Field java/lang/System.out:Ljava/io/PrintStream;
23: aload_1
24: arraylength
25: invokevirtual   #4; //Method java/io/PrintStream.println:(I)V
28: getstatic   #3; //Field java/lang/System.out:Ljava/io/PrintStream;
31: aload_2
32: invokevirtual   #5; //Method java/lang/String.length:()I
35: invokevirtual   #4; //Method java/io/PrintStream.println:(I)V

Dalam kasus pertama (20-25) kode hanya meminta JVM untuk ukuran array (di JNI ini akan menjadi panggilan ke GetArrayLength ()) sedangkan dalam kasus String (28-35) perlu melakukan a metode panggilan untuk mendapatkan panjangnya.

Pada pertengahan 1990-an, tanpa JIT dan sejenisnya yang bagus, akan mematikan kinerja jika hanya memiliki java.util.Vector (atau yang serupa) dan bukan konstruksi bahasa yang tidak benar-benar berperilaku seperti sebuah kelas tapi cepat. Mereka tentu saja bisa menutupi properti sebagai pemanggilan metode dan menanganinya di kompiler tetapi saya pikir akan lebih membingungkan untuk memiliki metode pada sesuatu yang bukan kelas nyata.

Fredrik
sumber
1
Java memperlakukan array sebagai objek dan string sebagai objek yang tidak dapat diubah !! : |
Nitish Upreti
@Myth: Saya tidak mengerti maksud Anda ... Properti panjang array bukanlah bidang publik atau apa pun, ini adalah konstruksi dari jvm (panjang array bahkan merupakan operasi di bytecode). Sangat jelas ketika Anda melakukan JNI atau jika Anda hanya membongkar kode darimana asalnya.
Fredrik
Saya tidak berpikir bahwa alasan desain aslinya hanya untuk performa. Bagaimana Anda akan mengimplementasikan Vectorketika bahasa Java tidak memiliki dukungan array?
Holger
8

.lengthadalah properti satu kali dari Java. Ini digunakan untuk mencari ukuran array berdimensi tunggal .

.length()adalah sebuah metode. Ini digunakan untuk mencari panjang a String. Ini menghindari duplikasi nilai.

Prabandha
sumber
8

Mempertimbangkan:

int[] myArray = new int[10];
String myString = "hello world!";
List<int> myList = new ArrayList<int>();

myArray.length    // Gives the length of the array
myString.length() // Gives the length of the string
myList.size()     // Gives the length of the list

Sangat mungkin bahwa string dan array dirancang pada waktu yang berbeda dan karenanya menggunakan konvensi yang berbeda. Satu pembenaran adalah karena String menggunakan array secara internal, sebuah metode, length()digunakan untuk menghindari duplikasi informasi yang sama. Lain adalah bahwa menggunakan metode length()membantu menekankan kekekalan string, meskipun ukuran array juga tidak dapat diubah.

Pada akhirnya, ini hanyalah inkonsistensi yang berkembang yang pasti akan diperbaiki jika bahasa tersebut didesain ulang dari awal. Sejauh yang saya tahu tidak ada bahasa lain (C #, Python, Scala, dll.) Yang melakukan hal yang sama, jadi ini mungkin hanya sedikit kekurangan yang berakhir sebagai bagian dari bahasa tersebut.

Anda akan mendapatkan kesalahan jika Anda tetap menggunakan yang salah.

Gordon Gustafson
sumber
Ini adalah jawaban yang lebih bisa dibenarkan dan tidak bias.
Zubair Alam
3

Di Java, Array menyimpan panjangnya secara terpisah dari struktur yang menyimpan data. Saat Anda membuat Array, Anda menentukan panjangnya, dan itu menjadi atribut yang menentukan Array. Tidak peduli apa yang Anda lakukan pada Array dengan panjang N (nilai perubahan, hal-hal nol, dll.), Itu akan selalu menjadi Array dengan panjang N.

Panjang String adalah insidental; itu bukan atribut dari String, tetapi produk sampingan. Meskipun String Java pada kenyataannya tidak dapat diubah, jika memungkinkan untuk mengubah isinya, Anda dapat mengubah panjangnya. Menghentikan karakter terakhir (jika memungkinkan) akan menurunkan panjangnya.

Saya mengerti bahwa ini adalah perbedaan yang bagus, dan saya mungkin akan ditolak, tetapi itu benar. Jika saya membuat Array dengan panjang 4, panjang empat itu adalah karakteristik yang menentukan dari Array, dan benar terlepas dari apa yang ada di dalamnya. Jika saya membuat String yang berisi "dogs", String itu panjangnya 4 karena kebetulan berisi empat karakter.

Saya melihat ini sebagai pembenaran untuk melakukan satu dengan atribut dan yang lainnya dengan metode. Sebenarnya, ini mungkin hanya ketidakkonsistenan yang tidak disengaja, tetapi selalu masuk akal bagi saya, dan selalu begini cara saya memikirkannya.

jakeboxer
sumber
2

Saya diajari bahwa untuk array, panjang tidak diambil melalui metode karena ketakutan berikut: programmer hanya akan menetapkan panjang ke variabel lokal sebelum memasuki loop (pikirkan loop for di mana kondisional menggunakan panjang array.) seharusnya melakukannya untuk memangkas pemanggilan fungsi (dan dengan demikian meningkatkan kinerja.) Masalahnya adalah bahwa panjang dapat berubah selama loop, dan variabel tidak.

Matthew
sumber
10
Panjang array tidak bisa berubah selama loop.
Fredrik
2
Anda tidak dapat mengubah panjang larik khusus ini, tetapi Anda dapat menetapkan yang baru ke variabel yang sama
Bozho
2
@Bozho: Benar, tapi kemudian itu adalah array lain dan jika Anda melakukannya dengan sengaja dan tidak memperbarui apa pun yang Anda periksa loop Anda apakah Anda memiliki bug. Java tidak pernah berniat menghentikan Anda dari menulis bug. Anda dapat melakukan loop tak terbatas, rekursi sampai Anda mati dan semua jenis kesalahan logis tanpa java mencoba menghentikan Anda darinya. Ini adalah alasan yang baik untuk tidak menyimpan panjang dalam variabel tetapi jelas bukan alasan mengapa ia dirancang seperti itu.
Fredrik
1

Setiap kali sebuah array dibuat, ukurannya ditentukan. Jadi panjangnya dapat dianggap sebagai atribut konstruksi. Untuk String, ini pada dasarnya adalah array karakter. Panjang adalah properti dari array karakter. Tidak perlu menempatkan panjang sebagai bidang, karena tidak semuanya membutuhkan bidang ini. http://www.programcreek.com/2013/11/start-from-length-length-in-java/

Ryan
sumber
0

Saya hanya ingin menambahkan beberapa komentar untuk jawaban hebat dari Fredrik .

The Java Language Specification dalam Bagian 4.3.1 negara

Sebuah objek adalah contoh kelas atau array yang .

Jadi array memang memiliki peran yang sangat spesial di Java. Aku heran kenapa.

Orang dapat berargumen bahwa array implementasi saat ini penting untuk kinerja yang lebih baik. Tapi selain itu adalah struktur internal, yang tidak boleh diekspos.

Mereka tentu saja bisa menutupi properti sebagai pemanggilan metode dan menanganinya di kompiler tetapi saya pikir akan lebih membingungkan untuk memiliki metode pada sesuatu yang bukan kelas nyata.

Saya setuju dengan Fredrik, bahwa pengoptimalan kompilator yang cerdas akan menjadi pilihan yang lebih baik. Ini juga akan menyelesaikan masalah, bahwa meskipun Anda menggunakan properti untuk array, Anda belum menyelesaikan masalah untuk string dan jenis koleksi (tidak dapat diubah) lainnya, karena, misalnya, stringdidasarkan pada chararray seperti yang Anda lihat pada definisi kelas dari String:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {           
    private final char value[]; // ...

Dan saya tidak setuju dengan itu akan lebih membingungkan, karena array mewarisi semua metode darijava.lang.Object .

Sebagai seorang insinyur, saya benar-benar tidak menyukai jawaban "Karena selalu seperti ini." dan berharap akan ada jawaban yang lebih baik. Tetapi dalam kasus ini tampaknya demikian.

tl; dr

Menurut pendapat saya, ini adalah cacat desain Java dan seharusnya tidak diterapkan dengan cara ini.

Michael Dorner
sumber