Rumah pembangunan bahagian belakang Tutorial C#.Net String StringBuffer StringBuilder区别

String StringBuffer StringBuilder区别

Dec 20, 2016 pm 03:49 PM
jvm

String 字符串常量 
StringBuffer 字符串变量(线程安全) 
StringBuilder 字符串变量(非线程安全) 
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。 
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的: 
String S1 = “This is only a” + “ simple” + “ test”; 
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”); 
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个 
String S1 = “This is only a” + “ simple” + “test”; 其实就是: 
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如: 
String S2 = “This is only a”; 
String S3 = “ simple”; 
String S4 = “ test”; 
String S1 = S2 +S3 + S4; 
这时候 JVM 会规规矩矩的按照原来的方式去做 

在大部分情况下 StringBuffer > String 
StringBuffer 
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。 
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。 
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。 
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。 
在大部分情况下 StringBuilder > StringBuffer 
java.lang.StringBuilde 
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。 
========================================================================= 
String类详解 
1、String类是final的,不可被继承。 
2、String类是的本质是字符数组char[], 并且其值不可改变。PRivate final char value[]; 
然后打开String类的API文档,可以发现: 
3、String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫 

做"abc"对象的引用。 
4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。 
6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串, 

并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。 


5、创建字符串的方式很多,归纳起来有三类: 
其一,使用new关键字创建字符串,比如String s1 = new String("abc"); 
其二,直接指定。比如String s2 = "abc"; 
其三,使用串联生成新的字符串。比如String s3 = "ab" + "c"; 

二、String对象的创建 

String对象的创建也很讲究,关键是要明白其原理。 
原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象, 

如果不存在,则在池中创建一个字符串s,否则,不在池中添加。 

原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。 

原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢 

了!但绝不会在堆栈区再去创建该String对象。 

原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。 

另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到 

String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池 

中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。 

三、不可变类 
不可改变的字符串具有一个很大的优点:编译器可以把字符串设置为共享。 
不可变类String有一个重要的优点-它们不会被共享引用。 

是这样的,JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池 
定义一个string类型的变量有两种方式: 
string name= "tom "; 
string name =new string( "tom ") 
使用第一种方式的时候,就使用了串池, 
使用第二中方式的时候,就是一种普通的声明对象的方式 
如果你使用了第一种方式,那么当你在声明一个内容也是 "tom "的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string saname= "tom ",将会指向同一块内存 

另外关于string类型是不可改变的问题: 
string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name= "madding " 
那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个 "tom "没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。 
据说这样可以提高效率!!! 
=========================================================================final StringBuffer a = new StringBuffer("111");  
final StringBuffer b = new StringBuffer("222");  
a=b;//此句编译不通过  
final StringBuffer a = new StringBuffer("111");  
a.append("222");//编译通过   
可见,final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。 

String常量池问题的四个例子 
下面是几个常见例子的比较分析和理解: 

[1]  
String a = "a1";   
String b = "a" + 1;  
System.out.println((a == b)); //result = true 
String a = "atrue";   
String b = "a" + "true";   
System.out.println((a == b)); //result = true 
String a = "a3.4";   
String b = "a" + 3.4;   
System.out.println((a == b)); //result = true  
分析:JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。 

[2]  
String a = "ab";   
String bb = "b";   
String b = "a" + bb;   
System.out.println((a == b)); //result = false  
分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。 

[3] 
String a = "ab";   
final String bb = "b";  
String b = "a" + bb;   
System.out.println((a == b)); //result = true  
分析:和[3]中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。 
所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。 

[4]  
String a = "ab";   
final String bb = getBB();   
String b = "a" + bb;   
System.out.println((a == b)); //result = false   
private static String getBB() {  return "b";   }   
分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面程序的结果为false。 

通过上面4个例子可以得出得知: 

String  s  =  "a" + "b" + "c";      就等价于String s = "abc"; 

String  a  =  "a";     
String  b  =  "b";     
String  c  =  "c";     
String  s  =   a  +  b  +  c;     
这个就不一样了,最终结果等于:  

StringBuffer temp = new StringBuffer();     
temp.append(a).append(b).append(c);     
String s = temp.toString();   
由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码: 

public class Test {  
public static void main(String args[]) {  
String s = null;  
for(int i = 0; i < 100; i++) {  s += "a";  }  
}  
}   
每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。 如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行append操作。 

String对象的intern方法理解和分析 
public class Test4 {  
private static String a = "ab";   
public static void main(String[] args){ 
String s1 = "a";  
String s2 = "b"; 
String s = s1 + s2;  
System.out.println(s == a);//false  
System.out.println(s.intern() == a);//true   

}   
这里用到Java里面是一个常量池的问题。对于s1+s2操作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所以s与a的值是不相等的。而当调用s.intern()方法,却可以返回s在常量池中的地址值,因为a的值存储在常量池中,故s.intern和a的值相等。

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Alat pemantauan JVM yang diedarkan, sangat praktikal! Alat pemantauan JVM yang diedarkan, sangat praktikal! Aug 15, 2023 pm 05:15 PM

Projek ini direka untuk memudahkan pembangun memantau berbilang JVM hos jauh dengan lebih cepat Jika projek anda adalah Spring boot, ia adalah sangat mudah untuk disepadukan. Jika ia bukan but Spring, anda boleh cepat memulakan program but Spring dan memperkenalkannya sendiri pakej Jar sudah memadai

Penjelasan terperinci tentang parameter baris arahan JVM: senjata rahsia untuk mengawal operasi JVM Penjelasan terperinci tentang parameter baris arahan JVM: senjata rahsia untuk mengawal operasi JVM May 09, 2024 pm 01:33 PM

Parameter baris arahan JVM membolehkan anda melaraskan tingkah laku JVM pada tahap yang terperinci. Parameter biasa termasuk: Tetapkan saiz timbunan Java (-Xms, -Xmx) Tetapkan saiz generasi baharu (-Xmn) Dayakan pengumpul sampah selari (-XX:+UseParallelGC) Kurangkan penggunaan memori kawasan Survivor (-XX: -ReduceSurvivorSetInMemory) Hilangkan lebihan Hapuskan kutipan sampah (-XX:-EliminateRedundantGCs) Cetak maklumat kutipan sampah (-XX:+PrintGC) Gunakan pemungut sampah G1 (-XX:-UseG1GC) Tetapkan masa jeda kutipan sampah maksimum (-XX:MaxGCPauXX

Perkara utama pengurusan memori JVM dan langkah berjaga-jaga Perkara utama pengurusan memori JVM dan langkah berjaga-jaga Feb 20, 2024 am 10:26 AM

Perkara utama dan langkah berjaga-jaga untuk menguasai penggunaan memori JVM JVM (JavaVirtualMachine) ialah persekitaran di mana aplikasi Java dijalankan, dan yang paling penting ialah pengurusan memori JVM. Mengurus memori JVM dengan betul bukan sahaja dapat meningkatkan prestasi aplikasi, tetapi juga mengelakkan masalah seperti kebocoran memori dan limpahan memori. Artikel ini akan memperkenalkan perkara utama dan pertimbangan penggunaan memori JVM dan menyediakan beberapa contoh kod khusus. Pembahagian memori JVM Memori JVM terutamanya dibahagikan kepada kawasan berikut: Heap (He

Analisis fungsi dan prinsip mesin maya JVM Analisis fungsi dan prinsip mesin maya JVM Feb 22, 2024 pm 01:54 PM

Pengenalan kepada analisis fungsi dan prinsip mesin maya JVM: Mesin maya JVM (JavaVirtualMachine) ialah salah satu komponen teras bahasa pengaturcaraan Java, dan ia merupakan salah satu titik jualan terbesar Java. Peranan JVM adalah untuk menyusun kod sumber Java ke dalam kod bait dan bertanggungjawab untuk melaksanakan kod bait ini. Artikel ini akan memperkenalkan peranan JVM dan cara ia berfungsi serta menyediakan beberapa contoh kod untuk membantu pembaca memahami dengan lebih baik. Fungsi: Fungsi utama JVM adalah untuk menyelesaikan masalah mudah alih program Java pada platform yang berbeza.

Ralat Java: Ralat limpahan memori JVM, cara menangani dan mengelak Ralat Java: Ralat limpahan memori JVM, cara menangani dan mengelak Jun 24, 2023 pm 02:19 PM

Java ialah bahasa pengaturcaraan yang popular Semasa pembangunan aplikasi Java, anda mungkin menghadapi ralat limpahan memori JVM. Ralat ini biasanya menyebabkan aplikasi ranap, menjejaskan pengalaman pengguna. Artikel ini akan meneroka punca ralat limpahan memori JVM dan cara menangani dan mengelakkan ralat tersebut. Apakah ralat limpahan memori JVM? Mesin Maya Java (JVM) ialah persekitaran berjalan untuk aplikasi Java. Dalam JVM, memori dibahagikan kepada beberapa kawasan, termasuk timbunan, kawasan kaedah, tindanan, dll. Timbunan digunakan untuk menyimpan objek yang dicipta

Program Java untuk menyemak sama ada JVM ialah 32-bit atau 64-bit Program Java untuk menyemak sama ada JVM ialah 32-bit atau 64-bit Sep 05, 2023 pm 06:37 PM

Sebelum menulis program java untuk menyemak sama ada JVM adalah 32-bit atau 64-bit, mari kita bincangkan tentang JVM dahulu. JVM ialah mesin maya java, bertanggungjawab untuk melaksanakan bytecode. Ia adalah sebahagian daripada Java Runtime Environment (JRE). Kita semua tahu bahawa java adalah bebas platform, tetapi JVM bergantung pada platform. Kami memerlukan JVM berasingan untuk setiap sistem pengendalian. Jika kami mempunyai kod bait mana-mana kod sumber java, kami boleh menjalankannya dengan mudah pada mana-mana platform disebabkan oleh JVM. Keseluruhan proses pelaksanaan fail java adalah seperti berikut - Pertama, kami menyimpan kod sumber java dengan sambungan .java dan pengkompil menukarnya kepada kod bait dengan sambungan .class. Ini berlaku pada masa penyusunan. Sekarang, pada masa tayangan, J

Bagaimana untuk melaraskan saiz memori timbunan JVM dengan cekap? Bagaimana untuk melaraskan saiz memori timbunan JVM dengan cekap? Feb 18, 2024 pm 01:39 PM

Tetapan parameter memori JVM: Bagaimana untuk melaraskan saiz memori timbunan secara munasabah? Dalam aplikasi Java, JVM ialah komponen utama yang bertanggungjawab untuk menguruskan memori. Antaranya, ingatan timbunan digunakan untuk menyimpan contoh objek Tetapan saiz ingatan timbunan mempunyai kesan penting ke atas prestasi dan kestabilan aplikasi. Artikel ini akan memperkenalkan cara melaraskan saiz memori timbunan secara munasabah, dengan contoh kod tertentu. Pertama, kita perlu memahami beberapa pengetahuan asas tentang memori JVM. Memori JVM dibahagikan kepada beberapa kawasan, termasuk ingatan timbunan, ingatan tindanan, kawasan kaedah, dll. dalam

Menjelaskan prinsip kerja JVM: Penerokaan mendalam tentang prinsip mesin maya Java Menjelaskan prinsip kerja JVM: Penerokaan mendalam tentang prinsip mesin maya Java Feb 18, 2024 pm 12:28 PM

Penjelasan terperinci tentang prinsip JVM: Penerokaan mendalam tentang prinsip kerja mesin maya Java memerlukan contoh kod khusus 1. Pengenalan Dengan perkembangan pesat dan aplikasi meluas bahasa pengaturcaraan Java, Mesin Maya Java (JavaVirtualMachine, dirujuk sebagai JVM ) juga menjadi sangat diperlukan dalam pembangunan perisian. Sebagai persekitaran berjalan untuk program Java, JVM boleh menyediakan ciri merentas platform, membenarkan program Java berjalan pada sistem pengendalian yang berbeza. Dalam artikel ini, kita akan menyelidiki cara JVM berfungsi

See all articles