Da wir hier alle Aspekte der String-Klasse zusammenfassen müssen, stellen wir auch einige SCJP-Fragen. Wenn es Mängel gibt, teilen Sie mir dies bitte in den Kommentaren mit, vielen Dank.
1. Invarianter Modus:
Nachdem ein String-Objekt erstellt wurde, kann sein Wert nicht geändert werden.
String str1="hello";//创建一个对象hello,不会变; System.out.println(str1); str1+=" world!";//两个字符串对象粘粘,系统其实创建了一个新的对象,把Str1的指向改了,指向新的对象;hello就 //变成了垃圾; System.out.println(str1);
//Wenn Sie es weiterhin so erstellen, wirkt sich dies auf die Effizienz des Systems aus. Wenn Sie den Wert eines Zeichenfolgenobjekts häufig ändern möchten, verwenden Sie StringBuffer, um es zu beschreiben.
StringBuffer sb=new StringBuffer("["); sb.append("hehe"); sb.append("]");//append();不会制造垃圾,真正在改sb的值; System.out.println(sb);
2. Objektpool
Zunächst müssen Sie verstehen, dass Object obj = new Object();
obj eine Referenz auf das ist Objekt, das sich auf dem Stapel befindet, und new Object() ist das Objekt, das sich auf dem Stapel im Stapel befindet.
Es kann verstanden werden, dass obj das Seil ist, das an den Wasserstoffballon gebunden ist, und new Object() der Wasserstoffballon ist. Wir greifen auf das Objekt über die Referenz des Objekts zu, genau wie wir das Seil festhalten verhindern, dass der Wasserstoffballon wegläuft.
Es gibt zwei Hauptmethoden zum Erstellen eines Stirng-Objekts:
java 代码 String str1 = new String("abc"); Stirng str2 = "abc";
Obwohl beide Anweisungen einen Verweis auf ein String-Objekt zurückgeben, hat der JVM die Art und Weise, wie er damit umgeht, unterschiedlich . Beim ersten Typ erstellt der JVM sofort ein String-Objekt im Heap und gibt dann die Referenz des Objekts an den Benutzer zurück. Für den zweiten Typ verwendet jvm zunächst die Methode equal von String im intern verwalteten String-Pool, um herauszufinden, ob das String-Objekt im Objektpool gespeichert ist. Wenn ja, wird das vorhandene String-Objekt an den Benutzer zurückgegeben,
Stattdessen wird im Heap ein neues String-Objekt neu erstellt. Wenn kein solches String-Objekt im Objektpool vorhanden ist, erstellt jvm ein neues String-Objekt im Heap, gibt seine Referenz an den Benutzer zurück und fügt die Referenz hinzu Saiten kacken
l rein. Hinweis: Wenn Sie die erste Methode zum Erstellen eines Objekts verwenden, fügt die JVM das Objekt nicht aktiv in den Strings-Pool ein, es sei denn, das Programm ruft die interne Methode von String auf. Schauen Sie sich das folgende Beispiel an:
Java-Code
String str1 = new String("abc"); //jvm erstellt ein String-Objekt auf dem Heap
//jvm kann in den Strings nicht gefunden werden pool Der String mit dem Wert „abc“, also
//Erstelle ein String-Objekt auf dem Heap und füge die Referenz des Objekts zum Strings-Pool hinzu
//Zu diesem Zeitpunkt befinden sich zwei String-Objekte auf dem Heap
Stirng str2 = "abc"; //并没有创建对象,因为对象池里已经有"abc" 了 if(str1 == str2){ System.out.println("str1 == str2"); }else{ System.out.println("str1 != str2"); }
String str3 = "abc";
// Geben Sie also das Objekt, auf das str2 zeigt, direkt an str3 zurück, das heißt, str2 und str3 sind Referenzen, auf die verwiesen wird zum gleichen Objekt
if(str2 == str3){ System.out.println("str2 == str3"); }else{ System.out.println("str2 != str3"); }
3 String / StringBuffer / StringBuilder
Die String-Klasse ist eine String-Konstante, die eine unveränderliche Konstante. StringBuffer ist eine String-Variable und ihr Objekt kann erweitert und geändert werden.
StringBuffer sb=new StringBuffer("[");//创建StringBuffer对象 sb.append("hehe");//把hehe加入字符串,变成 "[hehe" sb.append("]");//append();不会制造垃圾,真正在改sb的值; System.out.println(sb); String str = sb.toString();//把"[hehe]",赋值给一个字符串对象str
StringBuilder sb=new StringBuilder("[");//创建StringBuilder对象 sb.append("hehe");//把hehe加入字符串,变成 "[hehe" sb.append("]");//append();不会制造垃圾,真正在改sb的值; System.out.println(sb); String str = sb.toString();//把"[hehe]",赋值给一个字符串对象str
API. Nach häufiger Nutzung werden Sie sich damit vertraut machen.
java.lang.String char charAt (int index) 返回index所指定的字符 String concat(String str) 将两字符串连接 boolean endsWith(String str) 测试字符串是否以str结尾 boolean equals(Object obj) 比较两对象 char[] getBytes 将字符串转换成字符数组返回 char[] getBytes(String str) 将指定的字符串转成制服数组返回 boolean startsWith(String str) 测试字符串是否以str开始 int length() 返回字符串的长度 String replace(char old ,char new) 将old用new替代 char[] toCharArray 将字符串转换成字符数组 String toLowerCase() 将字符串内的字符改写成小写 String toUpperCase() 将字符串内的字符改写成大写 String valueOf(Boolean b) 将布尔方法b的内容用字符串表示 String valueOf(char ch) 将字符ch的内容用字符串表示 String valueOf(int index) 将数字index的内容用字符串表示 String valueOf(long l) 将长整数字l的内容用字符串表示 String substring(int1,int2) 取出字符串内第int1位置到int2的字符串
[java] view plain copy import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; public class StringUsage { // 几个欧不太用的方法。 public static void main(String[] args) { // 判断字符串首/尾。 String contentS = "test String again. test "; System.out.println(contentS); System.out.println("contentS.startsWith(/"test/")/t" + contentS.startsWith("test")); System.out.println("contentS.endsWith(/"test/")/t" + contentS.endsWith("test")); // 忽略大小写的字符串比较方法。 System.out .println("contentS.compareToIgnoreCase(contentS.toUpperCase()))/t" + contentS.compareToIgnoreCase(contentS.toUpperCase())); // 不区分大小写的字符串比较。 Comparator<String> cmprStr = String.CASE_INSENSITIVE_ORDER; List<String> lstStr = new LinkedList<String>(); // 准备数据。 lstStr.add("test"); lstStr.add("Test"); lstStr.add("tEst"); lstStr.add("rest"); lstStr.add("sest"); // 不区分大小写的排序。 Collections.sort(lstStr, cmprStr); System.out.println(lstStr); // 区分大小写的排序。 Collections.sort(lstStr); System.out.println(lstStr); System.out.println("/ntest String.valueOf()"); // 用 valueOf 处理 null 对象的字符串转换。 try { String ss = null; System.out.println(ss); System.out.println(String.valueOf(null)); // 比较奇怪的地方 } catch (RuntimeException e1) { e1.printStackTrace(); } BigDecimal db = null; try { System.out.println(((BigDecimal)db).toString()); } catch (Exception e) { e.printStackTrace(); } try { System.out.println(String.valueOf(db)); } catch (Exception e) { e.printStackTrace(); } db = new BigDecimal("100.00"); try { System.out.println(((BigDecimal)db).toString()); } catch (Exception e) { e.printStackTrace(); } } }
String a="Hello World!"; String b="Hello World!"; a=b? a和b是否相等 ? 为什么? String a=new String("Hello World!"); String b="Hello World!"; a=b? a和b是否相等 ? 为什么?
Da der Standardwert eines Objekts null ist, ist der Standardwert von String ebenfalls null, aber es handelt sich um ein spezielles Objekt und weist einige Eigenschaften auf, die andere Objekte nicht haben.
2. new String() und new String("") deklarieren beide einen neuen leeren String, der kein Null ist.
3.
String str=new String („kvill“); Der Unterschied:
Hier sprechen wir nicht über den Heap oder den Stack, sondern stellen nur kurz das einfache Konzept des konstanten Pools vor.
Konstantenpool bezieht sich auf
einige Daten, die während der Kompilierung ermittelt und in der kompilierten .class-Datei gespeichert werden. Es umfasst Konstanten in Klassen, Methoden, Schnittstellen usw. sowie Zeichenfolgenkonstanten.
Sehen Sie sich Beispiel 1 an:
String s0="kvill"; String s1="kvill"; String s2="kv" + "ill"; System.out.println( s0==s1 ); System.out.println( s0==s2 );
结果为:
true
true
首先,我们要知道Java会确保一个字符串常量只有一个拷贝。
因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以
s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连
接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。所以我们得出s0==s1==s2;
用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String()
创建的字符串不放入常量池中,它们有自己的地址空间。
看例2:
String s0="kvill"; String s1=new String("kvill"); String s2="kv"+ new String("ill"); System.out.println( s0==s1 ); System.out.println( s0==s2 ); System.out.println( s1==s2 );
结果为:
false
false
false
例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创
建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译
期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。
4. String.intern():
再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()
方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了。
例3:
String s0= "kvill"; String s1=new String("kvill"); String s2=new String("kvill"); System.out.println( s0==s1 ); System.out.println( “**********” ); s1.intern(); s2=s2.intern(); //把常量池中"kvill"的引用赋给s2 System.out.println( s0==s1); System.out.println( s0==s1.intern() ); System.out.println( s0==s2 );
结果为:
false
**********
false //虽然执行了s1.intern(),但它的返回值没有赋给s1
true //说明s1.intern()返回的是常量池中”kvill”的引用
true
最后我再破除一个错误的理解:
有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局Strin
g表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把
他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:
看例4:
String s1=new String("kvill"); String s2=s1.intern(); System.out.println( s1==s1.intern() ); System.out.println( s1+" "+s2 ); System.out.println( s2==s1.intern() );
结果:
false
kvill kvill
true
在这个类中我们没有声名一个"kvill"常量,所以s1.intern()同new String("kvill")是不同的,当我们调用s1.intern()后就在常量池中新添加了一个"kvill"常量,原来的
不在常量池中的"kvill"仍然存在,也就不是“将自己的地址注册到常量池中”了。
s1==s1.intern()为false说明原来的“kvill”仍然存在;
s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。
5. 关于equals()和==:
这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。
6. 关于String是不可变的
这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:
String str=”kv”+”ill”+” “+”ans”;
就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”;
并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可 font-family: Arial;font-size:12px;">改变的。</span>
<span style="color: rgb(51, 51, 153); font-family: Arial;font-size:12px;">
</span>
<span style="color: rgb(51, 51, 153); font-family: Arial;font-size:12px;">
【相关推荐】
1. java中String是对象还是类?详解java中的String
3. Java中String类的常用方法是什么?总结Java中String类的常用方法
Das obige ist der detaillierte Inhalt vonFassen Sie die Beispiel-Tutorials der String-Klasse in Java zusammen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!