Bagaimana sebuah string dapat diinisialisasi menggunakan ""?

154

Jika String adalah kelas seperti yang lainnya, bagaimana bisa diinisialisasi menggunakan tanda kutip ganda?

splitgames
sumber
25
String adalah kelas VIP. " "sudah menjadi String!
johnchen902
2
Tidak ada arti khusus. Maksud saya Sangat Penting. Artinya, java.lang.Stringmendapat perlakuan khusus Bahasa Jawa.
johnchen902
16
Siapa bilang string itu "kelas seperti yang lain"? Ini adalah kelas yang sangat istimewa, tidak seperti yang lain. Karena anggapan Anda salah, pertanyaannya tidak benar-benar dapat dijawab.
Eric Lippert
5
Hanya karena anggapan itu salah, bukan berarti pertanyaan tidak bisa dijawab. Dan jawaban yang benar sudah memiliki 197 suara.
Koray Tugay

Jawaban:

293

String Java adalah Spesial

Para perancang Jawa memutuskan untuk mempertahankan tipe primitif dalam bahasa berorientasi objek, alih-alih menjadikan segala sesuatu objek, sehingga dapat meningkatkan kinerja bahasa. Primitif disimpan dalam tumpukan panggilan, yang membutuhkan ruang penyimpanan lebih sedikit dan lebih murah untuk dimanipulasi. Di sisi lain, objek disimpan dalam tumpukan program, yang membutuhkan manajemen memori yang kompleks dan lebih banyak ruang penyimpanan.

Untuk alasan kinerja, Java's String dirancang untuk berada di antara primitif dan kelas.

Sebagai contoh

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

masukkan deskripsi gambar di sini

Catatan: String literal disimpan di kumpulan yang umum. Ini memfasilitasi berbagi penyimpanan untuk string dengan konten yang sama untuk menghemat penyimpanan. Stringobjek yang dialokasikan melalui operator baru disimpan di heap, dan tidak ada pembagian penyimpanan untuk konten yang sama.

Suresh Atta
sumber
72
Perhatikan bahwa "kolam umum" biasanya merupakan bagian dari heap.
Joachim Sauer
3
@ JoachimSauer Ya..dengan sedikit manfaat :) menambahkan itu dalam catatan. Terima kasih untuk mengingat.
Suresh Atta
2
Jadi apakah lebih cepat menulis String s1 = "Hello"; dari pada String s2 = String baru ("Halo") ;?
user2097804
28
Saya akan menambahkan itu dalam contoh Anda s1 == s2 == s3 tetapi s4! = S5
Alfredo Osorio
8
@AndrewJanke pada hotspot jvm baru-baru ini (7), string pool tidak dalam perm gen dan dari Java 8 tidak ada perm gen lagi ...
assylias
50

Java memperlakukan String sebagai kelas khusus, Anda dapat menginisialisasi dengan dua cara

  1. Langsung menetapkan literal

    String a = "adsasdf";
  2. Sebagai Objek lain menggunakan kata kunci baru

    String a = new String("adsasdf");

Anda harus berhati-hati ketika ingin membandingkan dengan ==tanda:

String a = "asdf";
String b = "asdf";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True

String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b);  // False
System.out.println(a.equals(b)); // True

Itu karena dalam kasus pertama objek a dan b disimpan dalam sesuatu yang disebut literal pooldan mereka berdua merujuk objek yang sama sehingga keduanya sama dalam kedua cara.

Tetapi dalam kasus kedua a dan b merujuk objek yang berbeda seperti ketika kita menginisialisasi objek lain. sehingga mereka tidak setara bila dibandingkan dengan ==operator sedangkan mereka memiliki nilai yang sama.

chetan
sumber
18

String mendapat perlakuan khusus di JLS: itu adalah salah satu dari dua jenis non-primitif yang ada literal (yang lain adalah Class) * .

Dari JLS :

String literal adalah referensi ke turunan dari kelas `String [...].

* yah, ada juga "null type" dengan "null literal" null, tetapi kebanyakan orang tidak menganggap "null type" sebagai tipe yang tepat.

Joachim Sauer
sumber
1
Saya juga tidak menyadari bahwa "null type" adalah tipe yang tepat di Jawa. Informasi ini sangat membantu, Anda harus meningkatkan ukuran font.
Grijesh Chauhan
1
@GrijeshChauhan: yah, "tipe null" hanya kata-kata yang bagus untuk memungkinkan siapa pun nulluntuk ditugaskan ke variabel tipe referensi apa pun. Itu bukan tipe yang menarik.
Joachim Sauer
15

Ini adalah fitur dari bahasa Jawa. Literal string dalam kode sumber diberikan perlakuan khusus.

Spesifikasi bahasa, di sini , hanya mengatakan bahwa string literal adalah Stringtipe

tidak
sumber
5

Teks di dalam tanda kutip ganda menciptakan Stringobjek literal .

String myString = "Some text";

Kode di atas membuat Stringobjek, menggunakan tanda kutip ganda.

tristan2468
sumber
4

String sangat sering digunakan dalam bahasa pemrograman. Karena java berorientasi objek, string adalah objek. Untuk menghindari String baru yang rumit ("someString"); pernyataan setiap kali Anda membutuhkan objek string java memungkinkan Anda untuk hanya membuat objek string dengan menggunakan string literal.

Tapi Anda harus ingat kesetaraan tali. Berikut tes singkat JUnit untuk menunjukkan apa yang saya maksud.

    @Test
    public void stringTest() {
       // a string literal and a string object created 
       // with the same literal are equal
       assertEquals("string", new String("string"));

       // two string literals are the same string object
       assertSame("string", "string"); 

       // a string literal is not the same object instance 
       // as a string object created with the same string literal
       assertFalse("string" == new String("string"));

       // java's String.intern() method gives you the same
       // string object reference for all strings that are equal.
       assertSame("string", new String("string").intern());
    }
René Link
sumber
Jika Anda hanya bisa menginisialisasi string new String(String src), maka Anda bahkan tidak akan bisa memberikan konstruktor literal string. Anda harus menginisialisasi char [], dan kemudian menggunakan String(char [] src)konsruktor untuk membangun string, atau Anda harus membaca string dari file.
AJMansfield
Itu tidak benar. String literal hanya urutan karakter dalam file sumber yang di-source oleh tanda kutip ganda. Java secara otomatis membuat instance string menggunakan literal ini. Oleh karena itu objek String literal dan sama, tetapi mereka tidak sama. Java juga bisa diimplementasikan dengan cara ini sehingga Anda harus menggunakan String baru (""); untuk instantiate objek String, tetapi ini hanya akan membuat hidup kita lebih sulit. Jadi ketika Anda menulis String baru ("string") java membuat objek String untuk literal "string" dan meneruskan objek string ini ke konstruktor String baru.
René Link
2

Hanya untuk menyebutkan. Literal string adalah referensi ke instance dari String kelas Anda dapat menulis kode seperti ini:

 "abc" .getBytes ();

 "a: b: c" .split (":");

 "愛" .codePointAt (0);
mkdev
sumber
2

- String adalah kelas di Jawa . Anda benar tentang hal itu, jadi kami selalu dapat menginisialisasi dengan newkata kunci.

- Tetapi ketika kita melakukan sesuatu seperti:

String s = "";

Pernyataan di atas ditandai oleh kompiler untuk menjadi objek String khusus dan kemudian JVM selama pemuatan kelas (memuat dilakukan sebelum inisialisasi), melihat ini yang dikenal sebagai string literal , yang disimpan dalam kumpulan string literal .

- Jadi String dapat dibuat menggunakan new()dan dengan ""metode ini, tetapi yang terakhir menyediakan string literal yang tetap di heap bahkan ketika tidak ada referensi ke objek string, karena memiliki referensi dari kumpulan string literal.

Kumar Vivek Mitra
sumber
2

Java melakukan proses dua langkah untuk kita.

String str = "hello";

setara dengan

char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);

Seperti [.NET] [1] mendapat hal serupa.

String(Char[]) constructor

tidak

String(char[] value)

Menambahkan referensi: -

pengguna1769790
sumber
2
Proses yang Anda gambarkan bukanlah apa yang sebenarnya dilakukan Java: Seperti yang telah dinyatakan orang lain, "hello"adalah string literal dan akan dimasukkan ke dalam kumpulan konstan oleh kompiler, lihat JLS §3.10.5 dan JVMS §5.1 .
siegi
1

Java.lang.Stringbukan hanya kelas. Ini merupakan bagian integral dari bahasa inti. Kompiler memiliki gula sintaksis untuk itu. Misalnya, ""seperti singkatan untuk new String(""). Ketika ditulis "", kompiler mengoptimalkan string identik ke instance yang sama untuk menghemat ruang."a" + 5 == "a5" ==> true

Kompiler memiliki gula sintaksis untuk banyak hal, termasuk tidak harus kotak / unbox antara versi objek dan jenis asli mereka, tidak ada induk berarti Obyek, konstruktor default, ...

Sylwester
sumber
5
""bukan singkatan untuk new String(""). Jika Anda menggunakan "", hal pertama yang akan dilakukan adalah mencari kecocokan di kumpulan String JVM dan jika itu benar, itu akan mengembalikan String itu. Dengan menggunakan new String(""), Anda akan selalu membuat String baru, bahkan jika String itu sendiri sudah ada di kolam String (karena itu tidak akan disimpan di kolam String).
g00glen00b
Saya memperbarui jawaban saya. Apakah orang menggunakan ini untuk keuntungan mereka, seperti menggunakan konstanta string seperti yang setara dengan jenis simbol Lisp?
Sylwester