Stringbuffer neden kesin?

Dize sınıfı değişmez ve bunun nedenlerinden biri de sınıfın kesin olarak ilan edilmesine rağmen diğer nedenler de vardır. Ama neden StringBuffer veya StringBuilder son ve hala değişkenler? Peki String'in değişmez olmasına hangi faktörler karar veriyor?

2
Bir sınıfın gerçekten değişmez olması için @jdphenix mutasyon eklemek için genişletilmekten kaçınmak için kesin olmalı
katma yazar Steve Kuo, kaynak
Bir sınıfın gerçekten değişmez olması için @jdphenix mutasyon eklemek için genişletilmekten kaçınmak için kesin olmalı
katma yazar Steve Kuo, kaynak
@JBNizet: Son cümlenin gerçekten doğru olduğundan emin değilim; yapıcıları özel paket yapmak ve sadece özel paket değişmez alt sınıflar (la ImmutableList ) sağlamak da yeterlidir.
katma yazar Louis Wasserman, kaynak
@JBNizet: Son cümlenin gerçekten doğru olduğundan emin değilim; yapıcıları özel paket yapmak ve sadece özel paket değişmez alt sınıflar (la ImmutableList ) sağlamak da yeterlidir.
katma yazar Louis Wasserman, kaynak
Değişmez bir sınıf, örnek durumu oluşturulduktan sonra değiştirilemeyen bir sınıftır. Son sınıf, genişletilemeyen bir sınıftır. Bunlar neredeyse dikey kavramlardır. Aralarındaki tek bağlantı, değişmez sınıfların nihai olmasıdır, böylece temel sınıfa değiştirilebilir durum ekleyecek alt sınıflar oluşturamazsınız.
katma yazar JB Nizet, kaynak
@LouisWasserman kabul etti. Sınıfın finalini yapmanın, alt sınıfların değişken durum eklemesini önlemenin tek yolu olduğunu kastetmedim. Demek istediğim, değişmez bir son olmayı seçtiğinde, nedenin alt sınıfların değişken bir durum eklemesini önlemektir. Aslında benim açımdan daha fazlasını kanıtlıyorsunuz: değişmezlik ve final sınıfları ortogonal kavramlardır: bir sınıf final olmadan değiştirilemez ve bir final sınıfı değiştirilebilir olabilir.
katma yazar JB Nizet, kaynak
@LouisWasserman kabul etti. Sınıfın finalini yapmanın, alt sınıfların değişken durum eklemesini önlemenin tek yolu olduğunu kastetmedim. Demek istediğim, değişmez bir son olmayı seçtiğinde, nedenin alt sınıfların değişken bir durum eklemesini önlemektir. Aslında benim açımdan daha fazlasını kanıtlıyorsunuz: değişmezlik ve final sınıfları ortogonal kavramlardır: bir sınıf final olmadan değiştirilemez ve bir final sınıfı değiştirilebilir olabilir.
katma yazar JB Nizet, kaynak
Değişmez bir sınıf, örnek durumu oluşturulduktan sonra değiştirilemeyen bir sınıftır. Son sınıf, genişletilemeyen bir sınıftır. Bunlar neredeyse dikey kavramlardır. Aralarındaki tek bağlantı, değişmez sınıfların nihai olmasıdır, böylece temel sınıfa değiştirilebilir durum ekleyecek alt sınıflar oluşturamazsınız.
katma yazar JB Nizet, kaynak
Sanırım final kavramını, yani genişletilemez ve değiştirilemez.
katma yazar jdphenix, kaynak
katma yazar jdphenix, kaynak
katma yazar jdphenix, kaynak
@ SteveKuo Katılıyorum. abhilash, final sınıfının doğası gereği değişmez olduğuna ve açıkça doğru olmadığına inandıklarına inanıyor gibi görünüyor. Ancak yanlış okumuş olabilirim.
katma yazar jdphenix, kaynak
@ SteveKuo Katılıyorum. abhilash, final sınıfının doğası gereği değişmez olduğuna ve açıkça doğru olmadığına inandıklarına inanıyor gibi görünüyor. Ancak yanlış okumuş olabilirim.
katma yazar jdphenix, kaynak
Peki şimdi sorunuz ne? Neden StringBuilder vs.'nin final olduğunu bilmek ister misiniz ya da String 'un ne değişken hale geldiğini bilmek ister misiniz?
katma yazar Holger, kaynak
Peki şimdi sorunuz ne? Neden StringBuilder vs.'nin final olduğunu bilmek ister misiniz ya da String 'un ne değişken hale geldiğini bilmek ister misiniz?
katma yazar Holger, kaynak
İlgili tartışma
katma yazar cDima, kaynak
İlgili tartışma
katma yazar cDima, kaynak
@jdphenix Bir sınıfa son bir değiştiricinin ne yaptığını biliyorum, ancak String sınıfının değişmez olduğu konusunda kafam karıştı, çünkü her yerde final olduğunu söylüyorlar.
katma yazar Abhilash28, kaynak
@jdphenix Bir sınıfa son bir değiştiricinin ne yaptığını biliyorum, ancak String sınıfının değişmez olduğu konusunda kafam karıştı, çünkü her yerde final olduğunu söylüyorlar.
katma yazar Abhilash28, kaynak

13 cevap

StringBuffer and StringBuilder are mainly used for string concatenating operations within a single method, the code using them often being generating by the compiler. So being extended is not the typical use case.

Öte yandan, final olmak, en azından geçmişte bir JVM içinde daha iyi optimizasyonlara izin verir; bugünün HotSpot JVM’i gerektirmiyor, ancak final bildirimini bu sınıflardan değiştirmek için hiçbir neden yoktu.

Unutmayın ki StringBuilder ve polimorfik davranış için geçersiz kılma yöntemleri, JRE'nin içinde StringBuilder 'ı kabul etmeden veya geri döndürmede hiçbir public yöntemi olmadığından biraz anlamsız olacaktır. örnek (ayrıca StringBuilder 'in kendi içinde). Eklenebilir ve CharSequence bu boşluğu doldurmak ve daha fazla esneklik sunmak.

değişkenlik ve değişkenlik kavramları, final sınıfları konseptinden tamamen farklıdır. Onlar sadece bir sınıfın nasıl bir yöntem veya işlem sağladığına bağlıdır. String , StringBuffer ve StringBuilder gibi yöntemlere sahipken içeriğini değiştirmeye izin veren hiçbir yöntem içermez. Değişmez bir sınıfın final olarak bildirilmesi, yalnızca mutasyonu destekleyen yöntemler getirebilecek alt sınıfların yasaklanmasına yardımcı olur, ancak bu zor bir gereklilik değildir.

3
katma

String'in nihai ve değişmez olması neden aslında iki , kısmen bağımsız sorulardır.

Birincisi, dize, java.lang paketinin bir parçasıdır, çünkü ad bu paketteki türlerin java dilini tanımına uygulamakla ilgili olduğunu ileri sürer. Bu, nihai olmasının bir nedeni, eğer bir dize alırsam bir dize alırsam güvenebilirim , bir dize davranırken java dili tanımlandığı gibi çünkü farklı davranışa sahip kendi alt sınıfınızı oluşturamazsınız).

İkincisi, String'in değişmezliği bir tasarım seçeneğidir, "sadece" bir seçimdir, ancak yine de bir String'i bir yere ilettiğinizde (örn. Bir File adı olarak), denilen API'yi dizeyi değiştiremeyeceğinizden emin olabilirsiniz. doğrudan referansları saklar (eğer değişebiliyorsa bir kopyasını çıkarmanın aksine). Ayrıca, çok iş parçacıklı ortamlarda String ile çalışmayı önemli ölçüde kolaylaştırır.

Peki neden StringBuilder/Buffer final? Bu yine “sadece” bir tasarım seçimidir, ancak String için olduğu kadar arkasında hiçbir kesin ve açık gerekçe yoktur. Sadece böyle yaptılar.

2
katma

String'in nihai ve değişmez olması neden aslında iki , kısmen bağımsız sorulardır.

Birincisi, dize, java.lang paketinin bir parçasıdır, çünkü ad bu paketteki türlerin java dilini tanımına uygulamakla ilgili olduğunu ileri sürer. Bu, nihai olmasının bir nedeni, eğer bir dize alırsam bir dize alırsam güvenebilirim , bir dize davranırken java dili tanımlandığı gibi çünkü farklı davranışa sahip kendi alt sınıfınızı oluşturamazsınız).

İkincisi, String'in değişmezliği bir tasarım seçeneğidir, "sadece" bir seçimdir, ancak yine de bir String'i bir yere ilettiğinizde (örn. Bir File adı olarak), denilen API'yi dizeyi değiştiremeyeceğinizden emin olabilirsiniz. doğrudan referansları saklar (eğer değişebiliyorsa bir kopyasını çıkarmanın aksine). Ayrıca, çok iş parçacıklı ortamlarda String ile çalışmayı önemli ölçüde kolaylaştırır.

Peki neden StringBuilder/Buffer final? Bu yine “sadece” bir tasarım seçimidir, ancak String için olduğu kadar arkasında hiçbir kesin ve açık gerekçe yoktur. Sadece böyle yaptılar.

2
katma

Sınıfla birlikte kullanıldığında "final" anahtar kelimesi hakkında bir yanlış anlaşılma olduğunu düşünüyorum. Bir değişken nihai olarak bildirildiğinde, değeri başlatıldıktan sonra değişemez.

diğer bir deyişle

final int i=5;
      i++// Will give an error.

Ama:

In case of classes: Final keyword servers the purpose of making the class non-inheritable diğer bir deyişlethat class can't be sub-classed!. i.e.

final class question
{}
class answer extends question//Will give an error!!!
{}

Sorunuza cevap:

Şimdi, dize değişmezliği haklısınız çünkü bir dize nesnesi başlatıldıktan sonra değiştirilemez ve Stringbuilder ve Stringbuffer değişkendir (Vice - Versa) ve bunun sınıfların nihai olmasıyla ilgisi yoktur! Onları doğru bir şekilde sınıflandırmıyorsunuz!

Umarım yardımcı olmuşumdur!

Düzenle:

Stringbuilder'ın nasıl değişken olduğunu ve String'in olmadığını açıklamam gerektiğini düşünüyorum:

Bu kodu kodla açıklayacağım:

Stringbuilder a = new Stringbuilder("a");//Initial String!!
a.append("b"); //Now the String is ab!!

So, since the same object diğer bir deyişlea got its value changed it is known as mutable.(An object diğer bir deyişlecapable of changing its value after being initialized).

Şimdi Dize:

String a = "a";
a = a + "b"; //Explained below.

Bu size göre, a string nesnesinin değerini değiştirdiği ve dolayısıyla değişken olduğu görünebilir ancak Stringbuilder'ın çalıştığı sahnelerin arkasındaki gibi değildir. diğer bir deyişle derleyici tarafından yukarıdaki kodda yapılan asıl şey:

a = new StringBuilder(a.append("b")); //The actual code...

So, now the variable a stores the values "ab". I know this is confusing, but if you read my code precisely you will see that the object a never changed it's values it just got assigned a new value!! This is what is known as being immutable diğer bir deyişlean object cant change after being initialized!

umarım yardımcı olmuşumdur

1
katma
Ve string sınıfının ne kadar değişmez olduğunu soruyorsanız cevap gerçekten basittir! Java.lang.String sınıfındaki veri üyeleri kesindir !!!!
katma yazar Kaushal Jain, kaynak
Ve yukarıda, a değişkeninin "ab" değerini sakladığını belirtmeme rağmen, aslında java'daki değişkenlerin hiçbir değer kaydetmediğini unutmayın. Sadece hafızaya kaydedilmiş nesnenin hafıza referansını saklarlar ("new" anahtar kelimesi kullanılarak yaratılmıştır). Sadece açıklamada basit olması gerektiğini söyledim!
katma yazar Kaushal Jain, kaynak
Umarım düzenlememi görmüşsünüzdür!
katma yazar Kaushal Jain, kaynak
@ abhilash: Herhangi bir mutasyon yöntemini açığa vurmamak, alt sınıflamayı yasaklamak ve yöntemlerin sonuçlarının her zaman aynı olduğunu garanti etmek.
katma yazar Louis Wasserman, kaynak
Doğru ama o zaman onu değişmez yapan ne?
katma yazar Abhilash28, kaynak

Sınıfla birlikte kullanıldığında "final" anahtar kelimesi hakkında bir yanlış anlaşılma olduğunu düşünüyorum. Bir değişken nihai olarak bildirildiğinde, değeri başlatıldıktan sonra değişemez.

diğer bir deyişle

final int i=5;
      i++// Will give an error.

Ama:

In case of classes: Final keyword servers the purpose of making the class non-inheritable diğer bir deyişlethat class can't be sub-classed!. i.e.

final class question
{}
class answer extends question//Will give an error!!!
{}

Sorunuza cevap:

Şimdi, dize değişmezliği haklısınız çünkü bir dize nesnesi başlatıldıktan sonra değiştirilemez ve Stringbuilder ve Stringbuffer değişkendir (Vice - Versa) ve bunun sınıfların nihai olmasıyla ilgisi yoktur! Onları doğru bir şekilde sınıflandırmıyorsunuz!

Umarım yardımcı olmuşumdur!

Düzenle:

Stringbuilder'ın nasıl değişken olduğunu ve String'in olmadığını açıklamam gerektiğini düşünüyorum:

Bu kodu kodla açıklayacağım:

Stringbuilder a = new Stringbuilder("a");//Initial String!!
a.append("b"); //Now the String is ab!!

So, since the same object diğer bir deyişlea got its value changed it is known as mutable.(An object diğer bir deyişlecapable of changing its value after being initialized).

Şimdi Dize:

String a = "a";
a = a + "b"; //Explained below.

Bu size göre, a string nesnesinin değerini değiştirdiği ve dolayısıyla değişken olduğu görünebilir ancak Stringbuilder'ın çalıştığı sahnelerin arkasındaki gibi değildir. diğer bir deyişle derleyici tarafından yukarıdaki kodda yapılan asıl şey:

a = new StringBuilder(a.append("b")); //The actual code...

So, now the variable a stores the values "ab". I know this is confusing, but if you read my code precisely you will see that the object a never changed it's values it just got assigned a new value!! This is what is known as being immutable diğer bir deyişlean object cant change after being initialized!

umarım yardımcı olmuşumdur

1
katma
Ve string sınıfının ne kadar değişmez olduğunu soruyorsanız cevap gerçekten basittir! Java.lang.String sınıfındaki veri üyeleri kesindir !!!!
katma yazar Kaushal Jain, kaynak
Ve yukarıda, a değişkeninin "ab" değerini sakladığını belirtmeme rağmen, aslında java'daki değişkenlerin hiçbir değer kaydetmediğini unutmayın. Sadece hafızaya kaydedilmiş nesnenin hafıza referansını saklarlar ("new" anahtar kelimesi kullanılarak yaratılmıştır). Sadece açıklamada basit olması gerektiğini söyledim!
katma yazar Kaushal Jain, kaynak
Umarım düzenlememi görmüşsünüzdür!
katma yazar Kaushal Jain, kaynak
@ abhilash: Herhangi bir mutasyon yöntemini açığa vurmamak, alt sınıflamayı yasaklamak ve yöntemlerin sonuçlarının her zaman aynı olduğunu garanti etmek.
katma yazar Louis Wasserman, kaynak
Doğru ama o zaman onu değişmez yapan ne?
katma yazar Abhilash28, kaynak

String is not immutable because it is final; final and immutability are more or less orthogonal. Making a class final is part of one approach to making a class immutable, but making a class final is also part of a good programming practice in general no matter what behavior you want for the class.

Değişmez bir sınıf, dış kullanıcılar tarafından genişletilemez. Örneğin, kendi paketi içinde çeşitli uygulamalar olabilir. Guava'nın ImmutableMap , bu durumda sınıfın nihai olması gerekmez, ancak örneğin yapıcıları özel paket yapmak, böylece paket dışındaki kullanıcılar sınıfı genişletemez.

Bir final sınıfı, genişletilemeyen herhangi bir sınıftır. Etkili Java’daki birçok vakada bu uygulama önerilir - yani, sınıfı alt sınıfa uygun hale getirmek için açık bir nedeniniz olmadığında, bunu son yapmak genellikle iyi bir uygulamadır.

1
katma

String is not immutable because it is final; final and immutability are more or less orthogonal. Making a class final is part of one approach to making a class immutable, but making a class final is also part of a good programming practice in general no matter what behavior you want for the class.

Değişmez bir sınıf, dış kullanıcılar tarafından genişletilemez. Örneğin, kendi paketi içinde çeşitli uygulamalar olabilir. Guava'nın ImmutableMap , bu durumda sınıfın nihai olması gerekmez, ancak örneğin yapıcıları özel paket yapmak, böylece paket dışındaki kullanıcılar sınıfı genişletemez.

Bir final sınıfı, genişletilemeyen herhangi bir sınıftır. Etkili Java’daki birçok vakada bu uygulama önerilir - yani, sınıfı alt sınıfa uygun hale getirmek için açık bir nedeniniz olmadığında, bunu son yapmak genellikle iyi bir uygulamadır.

1
katma

StringBuffer was the concept of mutable String, that is thread-safe, that is, all operations performed on it are synchronized.

StringBuilder is recommended replacement for StringBuffer. It was introduced, when it came out, that synchronization is not used very often, when it comes to Strings.

String is just String. Why is it immutable? Perhaps the reason was thread-safety and cost of such. What if you want to store global String, that is read only? If it was mutable, then all reads must have been synchronized - an additional overhead, that is not necessary here.

Bu yüzden bu üç sınıf sağlandı - ne için ödemek istediğinizi siz seçtiniz.

Sizin de belirttiğiniz gibi, tüm bu sınıflar - String , StringBuilder ve StringBuffer kesindir. Sebep, bu sınıfların davranışını değiştiremezsiniz (ve yapmamalısınız).

Başka bir sınıf uygulamak, (örneğin) StringBuilder içeren ve genişletmek yerine benzer işlevsellik sağlamak daha iyidir.

İsterseniz, CharSequence - tüm bu sınıflar bu arayüzü uygular.

0
katma

StringBuffer was the concept of mutable String, that is thread-safe, that is, all operations performed on it are synchronized.

StringBuilder is recommended replacement for StringBuffer. It was introduced, when it came out, that synchronization is not used very often, when it comes to Strings.

String is just String. Why is it immutable? Perhaps the reason was thread-safety and cost of such. What if you want to store global String, that is read only? If it was mutable, then all reads must have been synchronized - an additional overhead, that is not necessary here.

Bu yüzden bu üç sınıf sağlandı - ne için ödemek istediğinizi siz seçtiniz.

Sizin de belirttiğiniz gibi, tüm bu sınıflar - String , StringBuilder ve StringBuffer kesindir. Sebep, bu sınıfların davranışını değiştiremezsiniz (ve yapmamalısınız).

Başka bir sınıf uygulamak, (örneğin) StringBuilder içeren ve genişletmek yerine benzer işlevsellik sağlamak daha iyidir.

İsterseniz, CharSequence - tüm bu sınıflar bu arayüzü uygular.

0
katma

Peki, String'in değişmez olmasına başka hangi faktörler karar veriyor?

Cevap, String sınıfının tüm veri üyesi son olduğu için basittir, bu da onu değişmez yapar.

Kendi sınıfınızı değişmez kılmak istiyorsanız, o sınıfın tüm veri üyelerini final yapın. Ve tüm son veri üyelerini kurucuda başlat, böylece bir kez başlattıklarında, hiç değişmedi.

Değişmezlik için String sınıf uygulaması göreceksiniz, şunları bulacaksınız:

private final char[] value;

Ve değerin başlangıcı, kurucu kısımda olacaktır:

public String(String toCopy){

     value = toCopy.value;

}

Ve StringBuffer sınıf uygulamasını görecekseniz, şunları bulacaksınız:

private char[] value;

public StringBuffer(String toCopy){

     value = toCopy.value;

}

Bu nedenle, yukarıdaki kodda görebileceğiniz gibi, String sınıfının değer veri üyesi bir kez başlatılacak ve StringBuffer sınıfının değer veri üyesi başlatılabilir ve birçok kez değiştirilebilir.

Bu, String sınıfını bir sınıf finali yapmadan değiştirilemez hale getirir.

0
katma

Peki, String'in değişmez olmasına başka hangi faktörler karar veriyor?

Cevap, String sınıfının tüm veri üyesi son olduğu için basittir, bu da onu değişmez yapar.

Kendi sınıfınızı değişmez kılmak istiyorsanız, o sınıfın tüm veri üyelerini final yapın. Ve tüm son veri üyelerini kurucuda başlat, böylece bir kez başlattıklarında, hiç değişmedi.

Değişmezlik için String sınıf uygulaması göreceksiniz, şunları bulacaksınız:

private final char[] value;

Ve değerin başlangıcı, kurucu kısımda olacaktır:

public String(String toCopy){

     value = toCopy.value;

}

Ve StringBuffer sınıf uygulamasını görecekseniz, şunları bulacaksınız:

private char[] value;

public StringBuffer(String toCopy){

     value = toCopy.value;

}

Bu nedenle, yukarıdaki kodda görebileceğiniz gibi, String sınıfının değer veri üyesi bir kez başlatılacak ve StringBuffer sınıfının değer veri üyesi başlatılabilir ve birçok kez değiştirilebilir.

Bu, String sınıfını bir sınıf finali yapmadan değiştirilemez hale getirir.

0
katma

Eğer endişe duyuyorsanız, StringBuilder veya StringBuffer'ın davranışını genişletmekle ilgiliyseniz, yine de miras yoluyla değil. Kompozisyon veya delegasyon yapabilirsiniz. Sınıflar String, StringBuffer, StringBuilder hepsi CharacterSequence uygular. Böylece, CharacterSequence'ı uygulayan bir sınıf yaratın ve tüm yöntemleri, oluşan StringBuffer veya StringBuilder'a devredin. Kalıtım Üzerine Kompozisyon, GoF’in altın kuralıdır - bkz. tartışma 'dan da.

Bir sınıf finali yapmak, ek ve daha güçlü bir kapsülleme katmanıdır - belki de kodun yazarı, söz konusu sınıfın bir alt sınıfının gerçekten temsili olamayacağını hissedebileceğinden, birinin davranışını uzatma yoluyla değiştirmemesi gerektiğini düşünmez. kendisi (dönüşüm açısından).

0
katma

Eğer endişe duyuyorsanız, StringBuilder veya StringBuffer'ın davranışını genişletmekle ilgiliyseniz, yine de miras yoluyla değil. Kompozisyon veya delegasyon yapabilirsiniz. Sınıflar String, StringBuffer, StringBuilder hepsi CharacterSequence uygular. Böylece, CharacterSequence'ı uygulayan bir sınıf yaratın ve tüm yöntemleri, oluşan StringBuffer veya StringBuilder'a devredin. Kalıtım Üzerine Kompozisyon, GoF’in altın kuralıdır - bkz. tartışma 'dan da.

Bir sınıf finali yapmak, ek ve daha güçlü bir kapsülleme katmanıdır - belki de kodun yazarı, söz konusu sınıfın bir alt sınıfının gerçekten temsili olamayacağını hissedebileceğinden, birinin davranışını uzatma yoluyla değiştirmemesi gerektiğini düşünmez. kendisi (dönüşüm açısından).

0
katma