Maison développement back-end Tutoriel 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的值相等。

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Un outil de supervision JVM distribué, très pratique ! Un outil de supervision JVM distribué, très pratique ! Aug 15, 2023 pm 05:15 PM

Ce projet est conçu pour permettre aux développeurs de surveiller plus rapidement plusieurs JVM hôtes distants. Si votre projet est Spring Boot, il est très facile à intégrer. S'il ne s'agit pas de Spring Boot, ne vous découragez pas. initialiser rapidement un programme de démarrage Spring et le présenter vous-même suffit.

Explication détaillée des paramètres de ligne de commande JVM : l'arme secrète pour contrôler le fonctionnement de la JVM Explication détaillée des paramètres de ligne de commande JVM : l'arme secrète pour contrôler le fonctionnement de la JVM May 09, 2024 pm 01:33 PM

Les paramètres de ligne de commande JVM vous permettent d'ajuster le comportement de la JVM à un niveau plus fin. Les paramètres communs incluent : Définir la taille du tas Java (-Xms, -Xmx) Définir la taille de la nouvelle génération (-Xmn) Activer le garbage collector parallèle (-XX:+UseParallelGC) Réduire l'utilisation de la mémoire de la zone Survivor (-XX : -ReduceSurvivorSetInMemory) Éliminer la redondance Éliminer le garbage collection (-XX:-EliminateRedundantGCs) Imprimer les informations sur le garbage collection (-XX:+PrintGC) Utiliser le garbage collector G1 (-XX:-UseG1GC) Définir le temps de pause maximum du garbage collection (-XX:MaxGCPau

Points clés et précautions relatifs à la gestion de la mémoire JVM Points clés et précautions relatifs à la gestion de la mémoire JVM Feb 20, 2024 am 10:26 AM

Points clés et précautions pour maîtriser l'utilisation de la mémoire de la JVM La JVM (JavaVirtualMachine) est l'environnement dans lequel s'exécutent les applications Java, et le plus important est la gestion de la mémoire de la JVM. Une gestion correcte de la mémoire JVM peut non seulement améliorer les performances des applications, mais également éviter des problèmes tels que des fuites et des débordements de mémoire. Cet article présentera les points et considérations clés de l'utilisation de la mémoire JVM et fournira quelques exemples de code spécifiques. Partitions de mémoire JVM La mémoire JVM est principalement divisée dans les zones suivantes : Heap (Heap)

Analyse des fonctions et principes de la machine virtuelle JVM Analyse des fonctions et principes de la machine virtuelle JVM Feb 22, 2024 pm 01:54 PM

Une introduction à l'analyse des fonctions et des principes de la machine virtuelle JVM : La machine virtuelle JVM (JavaVirtualMachine) est l'un des composants centraux du langage de programmation Java, et c'est l'un des principaux arguments de vente de Java. Le rôle de la JVM est de compiler le code source Java en bytecodes et d'être responsable de l'exécution de ces bytecodes. Cet article présentera le rôle de la JVM et son fonctionnement, et fournira quelques exemples de code pour aider les lecteurs à mieux comprendre. Fonction : La fonction principale de JVM est de résoudre le problème de portabilité des programmes Java sur différentes plateformes.

Erreur Java : erreur de dépassement de mémoire JVM, comment gérer et éviter Erreur Java : erreur de dépassement de mémoire JVM, comment gérer et éviter Jun 24, 2023 pm 02:19 PM

Java est un langage de programmation populaire lors du développement d'applications Java, vous pouvez rencontrer des erreurs de dépassement de mémoire JVM. Cette erreur provoque généralement le crash de l'application, affectant l'expérience utilisateur. Cet article explorera les causes des erreurs de dépassement de mémoire JVM et comment gérer et éviter de telles erreurs. Qu’est-ce qu’une erreur de débordement de mémoire JVM ? La machine virtuelle Java (JVM) est l'environnement d'exécution des applications Java. Dans la JVM, la mémoire est divisée en plusieurs zones, notamment le tas, la zone de méthode, la pile, etc. Le tas est utilisé pour stocker les objets créés

Programme Java pour vérifier si la JVM est 32 bits ou 64 bits Programme Java pour vérifier si la JVM est 32 bits ou 64 bits Sep 05, 2023 pm 06:37 PM

Avant d'écrire un programme Java pour vérifier si la JVM est 32 bits ou 64 bits, parlons d'abord de la JVM. JVM est une machine virtuelle Java, responsable de l'exécution du bytecode. Il fait partie de Java Runtime Environment (JRE). Nous savons tous que Java est indépendant de la plate-forme, mais JVM dépend de la plate-forme. Nous avons besoin d'une JVM distincte pour chaque système d'exploitation. Si nous avons le bytecode de n’importe quel code source Java, nous pouvons facilement l’exécuter sur n’importe quelle plate-forme grâce à JVM. L'ensemble du processus d'exécution du fichier Java est le suivant - Tout d'abord, nous enregistrons le code source Java avec l'extension .java et le compilateur le convertit en bytecode avec l'extension .class. Cela se produit au moment de la compilation. Maintenant, au moment de l'exécution, J

Comment ajuster efficacement la taille de la mémoire tas JVM ? Comment ajuster efficacement la taille de la mémoire tas JVM ? Feb 18, 2024 pm 01:39 PM

Paramètres de mémoire JVM : comment ajuster raisonnablement la taille de la mémoire tas ? Dans les applications Java, la JVM est le composant clé responsable de la gestion de la mémoire. Parmi eux, la mémoire tas est utilisée pour stocker les instances d'objets. Le paramètre de taille de la mémoire tas a un impact important sur les performances et la stabilité de l'application. Cet article explique comment ajuster raisonnablement la taille de la mémoire du tas, avec des exemples de code spécifiques. Tout d’abord, nous devons comprendre quelques connaissances de base sur la mémoire JVM. La mémoire de la JVM est divisée en plusieurs zones, notamment la mémoire tas, la mémoire pile, la zone méthode, etc. dans

Démystifier le principe de fonctionnement de la JVM : exploration approfondie des principes de la machine virtuelle Java Démystifier le principe de fonctionnement de la JVM : exploration approfondie des principes de la machine virtuelle Java Feb 18, 2024 pm 12:28 PM

Explication détaillée des principes JVM : Une exploration approfondie du principe de fonctionnement de la machine virtuelle Java nécessite des exemples de code spécifiques 1. Introduction Avec le développement rapide et l'application généralisée du langage de programmation Java, la machine virtuelle Java (JavaVirtualMachine, appelée JVM ) est également devenu indispensable dans le développement de logiciels. En tant qu'environnement d'exécution des programmes Java, JVM peut fournir des fonctionnalités multiplateformes, permettant aux programmes Java de s'exécuter sur différents systèmes d'exploitation. Dans cet article, nous examinerons le fonctionnement de la JVM

See all articles