Apa yang dimaksud dengan abadi?


400

Ini bisa menjadi pertanyaan paling bodoh yang pernah diajukan tetapi saya pikir itu cukup membingungkan bagi seorang pemula Java.

  1. Adakah yang bisa menjelaskan apa yang dimaksud dengan abadi ?
  2. Mengapa tidak Stringberubah?
  3. Apa kelebihan / kekurangan benda yang tidak bisa diubah?
  4. Mengapa objek yang bisa berubah seperti StringBuilderlebih disukai daripada String dan sebaliknya?

Contoh yang bagus (di Jawa) akan sangat dihargai.


73
Lihat, itu bukan pertanyaan bodoh. Senang Anda bertanya!
DOK

2
Ngomong-ngomong, saya tidak berpikir itu pertanyaan paling bodoh yang pernah ada :) Saya pikir ini adalah konsep yang cukup penting untuk dipahami
Jason Coco

1
Ketika Anda mengatakan StringBuilder, bukankah Anda maksudkan StringBuffer kelas yang bisa berubah? Fungsi String dan StringBuffer lebih mirip daripada String dan StringBuilder. StringBuffer secara efektif adalah string yang bisa berubah.
Derek Mahar

3
Bolehkah saya menyarankan agar kami menambahkan tag "pemula" pada pertanyaan ini sehingga programmer yang baru ke Jawa dapat menemukannya dalam pencarian untuk pertanyaan pengantar lainnya?
Derek Mahar

Jawaban:


268

Immutable berarti bahwa begitu konstruktor untuk objek telah menyelesaikan eksekusi, instance itu tidak dapat diubah.

Ini berguna karena ini berarti Anda dapat meneruskan referensi ke objek di sekitarnya, tanpa khawatir orang lain akan mengubah isinya. Terutama ketika berhadapan dengan concurrency, tidak ada masalah penguncian dengan objek yang tidak pernah berubah

misalnya

class Foo
{
     private final String myvar;

     public Foo(final String initialValue)
     {
         this.myvar = initialValue;
     }

     public String getValue()
     {
         return this.myvar;
     }
}

Footidak perlu khawatir bahwa penelepon getValue()dapat mengubah teks dalam string.

Jika Anda membayangkan kelas yang mirip dengan Foo, tetapi dengan StringBuilderbukan Stringsebagai anggota, Anda dapat melihat bahwa penelepon getValue()akan dapat mengubah StringBuilderatribut Fooinstance.

Berhati-hatilah dengan berbagai jenis ketidakberdayaan yang mungkin Anda temukan: Eric Lippert menulis artikel blog tentang ini. Pada dasarnya Anda dapat memiliki objek yang antarmukanya tidak dapat diubah tetapi di balik layar, keadaan aktual yang dapat berubah menjadi privat (dan karenanya tidak dapat dibagi dengan aman di antara utas).


3
Saya pikir Anda harus menambahkan konstruktor satu arg untuk memberikan nilai setidaknya sekali. Poin dari kode saat ini tidak jelas karena tidak ada nilai untuk berubah benar-benar :).
Georgy Bolyuba

4
Anda harus membuat bidang hanya dibaca. Itu membuatnya sangat eksplisit bahwa bidang tidak dapat diubah. Sekarang ini tidak dapat diubah oleh konvensi
JaredPar

7
Anggota myVar harus final agar ini benar-benar abadi.
laz

13
Anda benar bahwa myVar tidak dapat diakses di luar Foo. Namun, kehadiran final menunjukkan kepada siapa pun yang dapat memodifikasi kelas di masa depan bahwa nilainya tidak dimaksudkan untuk berubah. Saya cenderung lebih suka bersikap sejelas mungkin dalam situasi seperti itu.
laz

2
Bagaimana dengan "Tipe referensi tidak dapat dibuat tidak berubah hanya dengan menggunakan kata kunci terakhir. Final hanya mencegah penugasan kembali." dari en.wikipedia.org/wiki/Immutable_object
Yousha Aleayoub

81

Objek yang tidak dapat diubah adalah objek di mana bidang internal (atau setidaknya, semua bidang internal yang memengaruhi perilaku eksternalnya) tidak dapat diubah.

Ada banyak keuntungan dari string yang tidak dapat diubah:

Kinerja: Lakukan operasi berikut:

String substring = fullstring.substring(x,y);

C yang mendasarinya untuk metode substring () mungkin kira-kira seperti ini:

// Assume string is stored like this:
struct String { char* characters; unsigned int length; };

// Passing pointers because Java is pass-by-reference
struct String* substring(struct String* in, unsigned int begin, unsigned int end)
{
    struct String* out = malloc(sizeof(struct String));
    out->characters = in->characters + begin;
    out->length = end - begin;
    return out;
}

Perhatikan bahwa tidak ada karakter yang harus disalin! Jika objek String dapat diubah (karakter dapat berubah nanti) maka Anda harus menyalin semua karakter, jika tidak, perubahan karakter dalam substring akan tercermin dalam string lain nanti.

Konkurensi: Jika struktur internal objek yang tidak dapat diubah valid, itu akan selalu valid. Tidak ada kemungkinan bahwa utas berbeda dapat membuat keadaan tidak valid dalam objek itu. Oleh karena itu, objek yang tidak berubah adalah Thread Safe .

Pengumpulan sampah: Jauh lebih mudah bagi pemulung untuk membuat keputusan logis tentang benda-benda yang tidak dapat diubah.

Namun, ada juga kerugian untuk ketidakberubahan:

Kinerja: Tunggu, saya pikir Anda mengatakan kinerja terbalik dari kekekalan! Ya, terkadang, tapi tidak selalu. Ambil kode berikut:

foo = foo.substring(0,4) + "a" + foo.substring(5);  // foo is a String
bar.replace(4,5,"a"); // bar is a StringBuilder

Kedua baris tersebut menggantikan karakter keempat dengan huruf "a". Tidak hanya potongan kode kedua yang lebih mudah dibaca, tetapi juga lebih cepat. Lihatlah bagaimana Anda harus melakukan kode yang mendasari untuk foo. Substring mudah, tetapi sekarang karena sudah ada karakter di ruang lima dan sesuatu yang lain mungkin merujuk foo, Anda tidak bisa begitu saja mengubahnya; Anda harus menyalin seluruh string (tentu saja beberapa fungsi ini diabstraksi menjadi fungsi dalam C yang mendasarinya, tetapi intinya di sini adalah untuk menunjukkan kode yang dieksekusi semua di satu tempat).

struct String* concatenate(struct String* first, struct String* second)
{
    struct String* new = malloc(sizeof(struct String));
    new->length = first->length + second->length;

    new->characters = malloc(new->length);

    int i;

    for(i = 0; i < first->length; i++)
        new->characters[i] = first->characters[i];

    for(; i - first->length < second->length; i++)
        new->characters[i] = second->characters[i - first->length];

    return new;
}

// The code that executes
struct String* astring;
char a = 'a';
astring->characters = &a;
astring->length = 1;
foo = concatenate(concatenate(slice(foo,0,4),astring),slice(foo,5,foo->length));

Perhatikan bahwa concatenate dipanggil dua kali yang berarti bahwa seluruh string harus diulang! Bandingkan ini dengan kode C untuk baroperasi:

bar->characters[4] = 'a';

Operasi string yang bisa berubah jelas jauh lebih cepat.

Kesimpulan: Dalam kebanyakan kasus, Anda ingin string yang tidak dapat diubah. Tetapi jika Anda perlu melakukan banyak menambahkan dan memasukkan ke dalam string, Anda membutuhkan kemampuan untuk berubah-ubah. Jika Anda ingin manfaat keamanan konkurensi dan pengumpulan sampah bersamanya kuncinya adalah menjaga objek Anda yang bisa berubah-ubah tetap lokal ke suatu metode:

// This will have awful performance if you don't use mutable strings
String join(String[] strings, String separator)
{
    StringBuilder mutable;
    boolean first = true;

    for(int i = 0; i < strings.length; i++)
    {
        if(!first) first = false;
        else mutable.append(separator);

        mutable.append(strings[i]);
    }

    return mutable.toString();
}

Karena mutableobjek adalah referensi lokal, Anda tidak perlu khawatir tentang keamanan konkurensi (hanya satu utas yang pernah menyentuhnya). Dan karena itu tidak direferensikan di tempat lain, itu hanya dialokasikan pada stack, jadi itu dialokasikan segera setelah panggilan fungsi selesai (Anda tidak perlu khawatir tentang pengumpulan sampah). Dan Anda mendapatkan semua manfaat kinerja dari mutabilitas dan imutabilitas.


4
Bagus dibaca! hanya satu hal yang saya pikir seharusnya jika (pertama) dan tidak jika (! pertama)
Siddhartha

Apa yang diperlukan bukanlah bahwa bidang tidak berubah, melainkan bahwa keadaan yang dapat diamati objek didefinisikan tidak berubah; sebuah objek yang memegang referensi ke objek lain sebagai alat enkapsulasi negara yang terkandung di dalamnya hanya dapat berubah jika semua aspek enkapsulasi negara yang terpapar ke dunia luar juga tidak dapat diubah. Perhatikan bahwa tidak perlu atau tidak cukup bahwa bidang menjadi tipe yang tidak dapat diubah. Yang penting adalah status kasat mata.
supercat

7
Passing pointers because Java is pass-by-referenceBukankah java "pass-by-value?"
Cristian Gutu

@CristianGutu ya Anda benar, JAVA adalah "Lewati Nilai" bukan "Lewati REFERENSI"
Arsh Kaushal

Referensi diberikan sebagai nilai !!
devv

31

Sebenarnya String tidak dapat diubah jika Anda menggunakan definisi wikipedia yang disarankan di atas.

Status string memang mengubah konstruksi pasca. Lihatlah metode kode hash (). String cache nilai kode hash di bidang lokal tetapi tidak menghitungnya sampai panggilan pertama kode hash (). Evaluasi malas hashcode ini menempatkan String dalam posisi yang menarik sebagai objek yang tidak berubah yang keadaannya berubah, tetapi tidak dapat diamati telah berubah tanpa menggunakan refleksi.

Jadi mungkin definisi yang tidak berubah harus menjadi objek yang tidak dapat diamati telah berubah.

Jika keadaan berubah pada objek yang tidak dapat diubah setelah dibuat tetapi tidak ada yang dapat melihatnya (tanpa refleksi) apakah objek tersebut masih tidak dapat diubah?


1
Ide bagus - sebuah objek yang tidak dapat diamati telah berubah, dan juga, tidak ada cara untuk mengubahnya dari luar. Bidang pribadi untuk kode hash () adalah perubahan internal yang tidak material ke keadaan objek yang terlihat secara eksternal.
mparaz

2
Sebenarnya bisa diamati telah berubah jika Anda menggunakan refleksi. Lihat lebih lanjut di Sedgewick's Strings yang dapat berubah jika Anda mengizinkan refleksi .
Miguel

24

Objek yang tidak dapat diubah adalah objek yang tidak dapat diubah secara terprogram. Mereka sangat baik untuk lingkungan multi-threaded atau lingkungan lain di mana lebih dari satu proses dapat mengubah (bermutasi) nilai-nilai dalam suatu objek.

Hanya untuk memperjelas, bagaimanapun, StringBuilder sebenarnya adalah objek yang bisa berubah, bukan yang tidak dapat diubah. String java biasa tidak dapat diubah (artinya setelah dibuat, Anda tidak dapat mengubah string yang mendasarinya tanpa mengubah objek).

Sebagai contoh, katakanlah saya memiliki kelas bernama ColoredString yang memiliki nilai String dan warna String:

public class ColoredString {

    private String color;
    private String string;

    public ColoredString(String color, String string) {
        this.color  = color;
        this.string = string;
    }

    public String getColor()  { return this.color;  }
    public String getString() { return this.string; }

    public void setColor(String newColor) {
        this.color = newColor;
    }

}

Dalam contoh ini, ColoredString dikatakan bisa berubah karena Anda dapat mengubah (bermutasi) salah satu properti kuncinya tanpa membuat kelas ColoredString baru. Alasan mengapa ini mungkin buruk adalah, misalnya, katakanlah Anda memiliki aplikasi GUI yang memiliki banyak utas dan Anda menggunakan ColoredStrings untuk mencetak data ke jendela. Jika Anda memiliki instance dari ColoredString yang telah dibuat sebagai

new ColoredString("Blue", "This is a blue string!");

Maka Anda akan mengharapkan string selalu menjadi "Biru". Namun, jika ada utas lainnya, dapatkan contoh ini dan menelepon

blueString.setColor("Red");

Anda tiba-tiba, dan mungkin secara tak terduga, sekarang memiliki string "Merah" ketika Anda menginginkan yang "Biru". Karena itu, objek yang tidak berubah hampir selalu lebih disukai ketika melewati contoh objek di sekitar. Ketika Anda memiliki kasus di mana objek yang dapat ditukar benar-benar diperlukan, maka Anda biasanya akan menjaga objek dengan hanya memberikan salinan dari bidang kontrol spesifik Anda.

Untuk rekap, di Jawa, java.lang.String adalah objek yang tidak dapat diubah ( tidak dapat diubah setelah dibuat) dan java.lang.StringBuilder adalah objek yang dapat diubah karena dapat diubah tanpa membuat instance baru.


Anda harus membuat bidang hanya dibaca. Saat ini kelas Anda tidak dapat diubah oleh konvensi. Tidak ada indikasi untuk pengembang masa depan bahwa kekekalan disengaja. Membuat bidang hanya dibaca akan membantu memperjelas niat Anda ke dev masa depan
JaredPar

@ JaredPar - Sebenarnya, kelasnya tidak berubah sama sekali ... ini adalah contoh dari kelas yang bisa berubah untuk menunjukkan mengapa ini bisa menjadi masalah.
Jason Coco

1
@JaredPar - Oh, itu tidak apa-apa :) Aku akan menulis ulang sedikit lebih jelas, tapi Douglas sudah ditulis dengan baik dan tampaknya menjadi favorit, jadi aku akan meninggalkan milikku sebagai contoh lain; tetapi seseorang benar-benar mengeditnya untuk membuat properti terakhir yang saya pikir lucu :)
Jason Coco

24
  1. Dalam aplikasi besar umum untuk string literal untuk menempati bit memori yang besar. Jadi untuk menangani memori secara efisien, JVM mengalokasikan area yang disebut "String constant pool". ( Catat bahwa dalam memori bahkan sebuah String yang tidak direferensikan membawa char [], sebuah int untuk panjangnya, dan yang lain untuk kode hashnya. Untuk angka , sebaliknya, maksimum delapan byte langsung diperlukan )
  2. Ketika complier menemukan String literal, ia memeriksa kumpulan untuk melihat apakah ada literal identik yang sudah ada. Dan jika ada yang ditemukan, referensi ke literal baru diarahkan ke String yang ada, dan tidak ada 'objek literal String' baru dibuat (String yang ada hanya mendapat referensi tambahan).
  3. Oleh karena itu: Mutabilitas string menghemat memori ...
  4. Tetapi ketika salah satu variabel mengubah nilai, Sebenarnya - hanya referensi mereka yang berubah, bukan nilai dalam memori (karenanya tidak akan mempengaruhi variabel lain yang merujuknya) seperti yang terlihat di bawah ini ....

String s1 = "String lama";

//s1 variable, refers to string in memory
        reference                 |     MEMORY       |
        variables                 |                  |

           [s1]   --------------->|   "Old String"   |

String s2 = s1;

//s2 refers to same string as s1
                                  |                  |
           [s1]   --------------->|   "Old String"   |
           [s2]   ------------------------^

s1 = "String Baru";

//s1 deletes reference to old string and points to the newly created one
           [s1]   -----|--------->|   "New String"   |
                       |          |                  |
                       |~~~~~~~~~X|   "Old String"   |
           [s2]   ------------------------^

String asli 'dalam memori' tidak berubah, tetapi variabel referensi diubah sehingga merujuk ke string baru. Dan jika kita tidak memiliki s2, "String Lama" akan tetap ada di memori tetapi kita tidak akan dapat mengaksesnya ...


16

"abadi" berarti Anda tidak dapat mengubah nilai. Jika Anda memiliki turunan dari kelas String, metode apa pun yang Anda panggil yang tampaknya mengubah nilai, sebenarnya akan membuat String lain.

String foo = "Hello";
foo.substring(3);
<-- foo here still has the same value "Hello"

Untuk mempertahankan perubahan, Anda harus melakukan sesuatu seperti ini foo = foo.sustring (3);

Immutable vs bisa berubah bisa lucu ketika Anda bekerja dengan koleksi. Pikirkan tentang apa yang akan terjadi jika Anda menggunakan objek yang bisa berubah sebagai kunci untuk peta dan kemudian ubah nilainya (tip: pikirkan tentang equalsdan hashCode).


13

waktu java

Mungkin agak terlambat tetapi untuk memahami apa objek abadi, pertimbangkan contoh berikut dari Java 8 Date and Time API ( java.time ) baru. Seperti Anda mungkin tahu semua objek tanggal dari Java 8 tidak dapat diubah, jadi dalam contoh berikut

LocalDate date = LocalDate.of(2014, 3, 18); 
date.plusYears(2);
System.out.println(date);

Keluaran:

2014-03-18

Ini mencetak tahun yang sama dengan tanggal awal karena plusYears(2)mengembalikan objek baru sehingga tanggal lama masih tidak berubah karena ini adalah objek yang tidak dapat diubah. Setelah dibuat, Anda tidak dapat memodifikasinya lebih lanjut dan variabel tanggal masih menunjukkannya.

Jadi, contoh kode itu harus menangkap dan menggunakan objek baru yang dipakai dan dikembalikan oleh panggilan itu ke plusYears.

LocalDate date = LocalDate.of(2014, 3, 18); 
LocalDate dateAfterTwoYears = date.plusYears(2);

date.toString ()… 2014-03-18

dateAfterTwoYears.toString ()… 2016-03-18


8

Saya sangat menyukai penjelasan dari SCJP Sun Certified Programmer untuk Java 5 Study Guide .

Untuk membuat Java lebih hemat memori, JVM menyisihkan area memori khusus yang disebut "string constant pool." Ketika kompiler menemukan String literal, ia memeriksa kumpulan untuk melihat apakah String yang identik sudah ada. Jika kecocokan ditemukan, referensi ke literal baru diarahkan ke String yang ada, dan tidak ada objek literal String baru dibuat.


Seharusnya bisa melakukan ini dengan objek abadi identik, tapi saya kira itu akan memakan waktu terlalu banyak.
Zan Lynx

8

Objek yang tidak berubah tidak dapat mengubah kondisinya setelah dibuat.

Ada tiga alasan utama untuk menggunakan objek yang tidak dapat diubah kapan pun Anda bisa, yang semuanya akan membantu mengurangi jumlah bug yang Anda perkenalkan dalam kode Anda:

  • Jauh lebih mudah untuk berpikir tentang bagaimana program Anda bekerja ketika Anda tahu bahwa keadaan suatu objek tidak dapat diubah dengan metode lain
  • Objek yang tidak dapat diubah secara otomatis di-thread-threaded (dengan asumsi mereka dipublikasikan dengan aman) sehingga tidak akan pernah menjadi penyebab bug multithreading yang sulit untuk dijabarkan
  • Objek yang tidak dapat diubah akan selalu memiliki kode Hash yang sama, sehingga mereka dapat digunakan sebagai kunci dalam HashMap (atau serupa). Jika kode hash elemen dalam tabel hash diubah, entri tabel akan hilang secara efektif, karena upaya untuk menemukannya di tabel akan berakhir dengan mencari di tempat yang salah. Ini adalah alasan utama bahwa objek String tidak dapat diubah - mereka sering digunakan sebagai kunci HashMap.

Ada juga beberapa optimisasi lain yang mungkin dapat Anda buat dalam kode ketika Anda tahu bahwa keadaan suatu objek tidak berubah - misalnya caching hash yang dihitung - tetapi ini adalah optimisasi dan oleh karena itu hampir tidak begitu menarik.


5

Satu makna berkaitan dengan bagaimana nilai disimpan di komputer, Untuk string .Net misalnya, itu berarti bahwa string dalam memori tidak dapat diubah, Ketika Anda berpikir Anda mengubahnya, Anda sebenarnya membuat yang baru string dalam memori dan menunjuk variabel yang ada (yang hanya pointer ke kumpulan karakter aktual di tempat lain) ke string baru.


4
String s1="Hi";
String s2=s1;
s1="Bye";

System.out.println(s2); //Hi  (if String was mutable output would be: Bye)
System.out.println(s1); //Bye

s1="Hi": sebuah objek s1dibuat dengan nilai "Hai" di dalamnya.

s2=s1 : sebuah objek s2dibuat dengan referensi ke objek s1.

s1="Bye": nilai s1objek sebelumnya tidak berubah karena s1memiliki tipe String dan tipe String adalah tipe yang tidak dapat diubah, sebagai gantinya kompiler membuat objek String baru dengan nilai "Bye" dan s1merujuknya. di sini ketika kita mencetak s2nilai, hasilnya akan menjadi "Hai" bukan "Sampai jumpa" karena s2direferensikan ke s1objek sebelumnya yang memiliki nilai "Hai".


dapatkah Anda menambahkan sedikit penjelasan?
minigeek

3

Immutable berarti bahwa setelah objek dibuat, yang bukan anggota akan berubah. Stringtidak dapat diubah karena Anda tidak dapat mengubah kontennya. Sebagai contoh:

String s1 = "  abc  ";
String s2 = s1.trim();

Dalam kode di atas, string s1 tidak berubah, objek lain ( s2) dibuat menggunakan s1.


3

Immutable berarti tidak dapat diubah atau tidak dapat dimodifikasi. Setelah objek string dibuat, data atau statusnya tidak dapat diubah

Pertimbangkan contoh di bawah ini,

class Testimmutablestring{  
  public static void main(String args[]){  
    String s="Future";  
    s.concat(" World");//concat() method appends the string at the end  
    System.out.println(s);//will print Future because strings are immutable objects  
  }  
 }  

Mari mendapatkan ide dengan mempertimbangkan diagram di bawah ini,

masukkan deskripsi gambar di sini

Dalam diagram ini, Anda dapat melihat objek baru yang dibuat sebagai "Dunia Masa Depan". Tetapi tidak mengubah "Masa Depan". Because String is immutable. s, masih merujuk ke "Masa Depan". Jika Anda perlu memanggil "Dunia Masa Depan",

String s="Future";  
s=s.concat(" World");  
System.out.println(s);//print Future World

Mengapa objek string tidak dapat diubah di java?

Karena Java menggunakan konsep string literal. Misalkan ada 5 variabel referensi, semua merujuk ke satu objek "Masa Depan". Jika satu variabel referensi mengubah nilai objek, itu akan terpengaruh ke semua variabel referensi. Itulah sebabnya objek string tidak dapat diubah di java.


2

Setelah diterapkan, tidak dapat diubah. Pertimbangkan kelas yang instance dapat digunakan sebagai kunci untuk hashtable atau serupa. Lihatlah praktik terbaik Java.


0

Objek yang Tidak Berubah

Suatu objek dianggap tidak berubah jika kondisinya tidak dapat berubah setelah dibangun. Ketergantungan maksimum pada objek yang tidak dapat diubah diterima secara luas sebagai strategi yang bagus untuk membuat kode yang sederhana dan andal.

Objek yang tidak dapat berubah sangat berguna dalam aplikasi berbarengan. Karena mereka tidak dapat mengubah keadaan, mereka tidak dapat rusak oleh gangguan utas atau diamati dalam keadaan tidak konsisten.

Pemrogram sering enggan untuk menggunakan objek yang tidak dapat diubah, karena mereka khawatir tentang biaya membuat objek baru sebagai lawan memperbarui objek di tempat. Dampak penciptaan objek sering kali terlalu tinggi, dan dapat diimbangi oleh beberapa efisiensi yang terkait dengan objek yang tidak dapat diubah. Ini termasuk penurunan overhead karena pengumpulan sampah, dan penghapusan kode yang diperlukan untuk melindungi objek yang bisa berubah dari korupsi.

Subbagian berikut mengambil kelas yang instansnya berubah dan berasal kelas dengan instance yang tidak dapat diubah darinya. Dengan melakukan hal itu, mereka memberikan aturan umum untuk konversi semacam ini dan menunjukkan beberapa keuntungan dari objek yang tidak dapat diubah.

Sumber


0

Karena jawaban yang diterima tidak menjawab semua pertanyaan. Saya terpaksa memberi jawaban setelah 11 tahun dan 6 bulan.

Adakah yang bisa menjelaskan apa yang dimaksud dengan abadi?

Semoga Anda maksud objek yang tidak dapat diubah (karena kita dapat memikirkan referensi yang tidak dapat diubah ).

Objek tidak berubah : jika pernah dibuat, mereka selalu mewakili nilai yang sama (tidak memiliki metode apa pun yang mengubah nilai).

Mengapa tidak Stringberubah?

Hormati definisi di atas yang dapat diperiksa dengan melihat ke dalam kode sumber Sting.java .

Apa kelebihan / kekurangan benda yang tidak bisa diubah? tipe abadi adalah:

  • lebih aman dari bug.

  • lebih mudah dimengerti.

  • dan lebih siap untuk perubahan.

Mengapa objek yang bisa berubah seperti StringBuilder lebih disukai daripada String dan sebaliknya?

Mempersempit pertanyaan Mengapa kita membutuhkan StringBuilder yang bisa berubah dalam pemrograman? Penggunaan umum untuk itu adalah untuk menggabungkan sejumlah besar string bersama, seperti ini:

String s = "";
for (int i = 0; i < n; ++i) {
    s = s + n;
}

Menggunakan string yang tidak dapat diubah, ini membuat banyak salinan sementara - nomor pertama dari string ("0") sebenarnya disalin n kali dalam proses membangun string terakhir, angka kedua disalin n-1 kali, dan sebagainya di. Sebenarnya biaya O (n2) waktu hanya untuk melakukan semua penyalinan itu, meskipun kita hanya menggabungkan n elemen.

StringBuilder dirancang untuk meminimalkan penyalinan ini. Ini menggunakan struktur data internal yang sederhana namun pintar untuk menghindari penyalinan sama sekali sampai akhir, ketika Anda meminta String terakhir dengan panggilan toString ():

StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; ++i) {
  sb.append(String.valueOf(n));
}
String s = sb.toString();

Mendapatkan kinerja yang baik adalah salah satu alasan mengapa kami menggunakan objek yang bisa berubah. Lain adalah berbagi nyaman: dua bagian dari program Anda dapat berkomunikasi lebih nyaman dengan berbagi struktur data yang bisa berubah-ubah.

Lebih banyak dapat ditemukan di sini: https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types


-1

Objek abadi adalah objek yang tidak dapat Anda modifikasi setelah Anda membuatnya. Contoh tipikal adalah string literal.

Bahasa pemrograman AD, yang menjadi semakin populer, memiliki gagasan "kekekalan" melalui kata kunci "invarian". Lihat artikel Dr.Dobb ini tentang hal itu - http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . Ini menjelaskan masalah dengan sempurna.


Saya percaya bahwa pada D 2.020 kata kunci diubah dari invarian menjadi tidak berubah. Saya tidak mengerti apa-apa, tetapi dikatakan, "sekarang tidak bisa diterapkan." digitalmars.com/d/2.0/changelog.html#new2_020
he_the_great
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.