深入 String 类
2016-03-16 11:05
447 查看
一,
二,
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
and the compilation unit:
produces the output:
This example illustrates six points:
1. Literal strings within the same class (§8) in the same package (§7) represent references
to the same String object (§4.3.1).
2. Literal strings within different classes in the same package represent references to the
same String object.
3. Literal strings within different classes in different packages likewise represent references
to the same String object.
4. Strings computed by constant expressions (§15.28) are computed at compile time and
then treated as if they were literals.
5. Strings computed by concatenation at run-time are newly created and therefore distinct.
6. The result of explicitly interning a computed string is the same string as any pre-existing
literal string with the same contents.
只要在编译时可以确定字符串的值,这个字符串都会存到String Pool中,并返回在Pool上的引用。
三,
四,
1. String,StringBuffer,StringBuilder均实现了CharSequence接口;
2. String对象具有不变性,只可读。任何看起来修改了String值的情况,都会创建一个新的String对象;
3. Java里面和C++不同的是,不允许重载运算符,用于String的+、+=是Java中仅有的两个重载过的操作符,所以说,Java里面的=,就是对于引用的赋值操作;
4. 对String类型的+操作实际上是通过创建并操作StringBuilder对象实现的,所以,当使用+处理的字符串比较复杂时,就应该选择创建StringBuilder对象,再使用StringBuilder中所提供的丰富的方法完成字符串的构建;
5. 在没有引入StringBuilder之前,Java使用的是StringBuffer,StringBuffer是线程安全的,因此开销大于StringBuilder,也就是说,使用StringBuilder速度更快。
public class String00 { public static void main(String[] args) { // 下面是 jdk 文档中关于字面值字符串对象的说明: // 原文:All string literals in Java programs, such as "abc", are // implemented as instances of this class. // 译文:Java 程序中所有的字符串字面值,例如 "abc" 等, 都是作为 String 类的实例被实现的。 // 输出 true,说明 s1 与 s2 的引用值相等。 // 这是由于 Java 中由 String 类维护一个 String Pool, // 当通过字面值方式给一个字符串对象赋值时, // 首先,会检查 String Pool 中有无该字符串,有, // 直接返回该字符串的地址值,无,先在其中创建这个字符串,然后返回其地址值。 // 针对以下代码: // 执行 s1 = "qp"; 时,String Pool 中没有字符串对象 "qp", // 于是首先创建该对象,然后返回其地址值; // 执行 s2 = "qp"; 时,String Pool 中已经存在字符串对象 "qp", // 因此直接返回其地址值,也就是说,这行代码不会创建一个新的对象。 // 由于 s1 与 s2 指向同一个地址,所以最后判断结果为 true。 String s1 = "qp"; String s2 = "qp"; System.out.println(s1 == s2); System.out.println("------------------"); // 使用加法连接字符串时会生成新的字符串对象,而不是向原有的 String 对象追加内容。 // 输出 false,说明 str 与 str3 的引用值不相等。 // 与下面的标号为 ① 的代码段结合起来看 < 该代码段执行结果亦为 false > // 执行 str3 = str1 + str2; 时,相当于执行 // str3 = new String(str1 + str2); // 这种使用 new 关键字给字符串对象赋值的方式执行流程为: // 首先,检查 String Pool 中是否存在字符串 str1 + str2, // 存在,直接在 heap 中创建字符串对象,然后返回其地址值 // 反之,则先在 String Pool 中创建该对象,然后再在 heap 中创建同样的一个对象,并返回其地址值。 // 这就是以下语句段返回 false 的原因。 String str = "hello"; String str1 = "hel"; String str2 = "lo"; String str3 = str1 + str2; // 运行时确定,在堆上,相当于new System.out.println(str == str3); System.out.println("------------------"); // ① String str4 = new String("hel" + "lo"); System.out.println(str == str4); System.out.println("-------------------"); // 直接进行 str5 = "hel" + "lo"; // 相当于 str5 = "hello"; // 故而会返回 true String str5 = "hel" + "lo"; // 不涉及堆 编译时确定 System.out.println(str == str5); System.out.println("--------------------"); // 补充:String Pool 位于栈中。 // intern() 返回字符串池中的字符串的引用,若没有该字符串(由equals判定),则新加入字符串再返回引用 String str6 = (str1 + str2).intern(); System.out.println(str == str6); } }
二,
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
package testPackage; class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); System.out.print((Other.hello == hello) + " "); System.out.print((other.Other.hello == hello) + " "); System.out.print((hello == ("Hel"+"lo")) + " "); System.out.print((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } }
class Other { static String hello = "Hello"; }
and the compilation unit:
package other; public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
This example illustrates six points:
1. Literal strings within the same class (§8) in the same package (§7) represent references
to the same String object (§4.3.1).
2. Literal strings within different classes in the same package represent references to the
same String object.
3. Literal strings within different classes in different packages likewise represent references
to the same String object.
4. Strings computed by constant expressions (§15.28) are computed at compile time and
then treated as if they were literals.
5. Strings computed by concatenation at run-time are newly created and therefore distinct.
6. The result of explicitly interning a computed string is the same string as any pre-existing
literal string with the same contents.
只要在编译时可以确定字符串的值,这个字符串都会存到String Pool中,并返回在Pool上的引用。
三,
/* * StringBuffer 类与 String 类不同 * StringBuffer 类所定义的是一个可变的字符串 * 如同 JDK 中所述: * A string buffer is like a String, but can be modified. At any point in time * it contains some particular sequence of characters, but * the length and content of the sequence can be changed through certain method * calls. */ public class TestStringBuffer { public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("hello").append(",world").append("!"); System.out.println(buffer); String str = buffer.toString(); System.out.println(str); buffer.append(true); System.out.println(buffer); String s1 = Integer.toString(10); String s2 = String.valueOf(20); System.out.println(s1 + s2); } }
hello,world! hello,world! hello,world!true 1020
四,
1. String,StringBuffer,StringBuilder均实现了CharSequence接口;
2. String对象具有不变性,只可读。任何看起来修改了String值的情况,都会创建一个新的String对象;
3. Java里面和C++不同的是,不允许重载运算符,用于String的+、+=是Java中仅有的两个重载过的操作符,所以说,Java里面的=,就是对于引用的赋值操作;
4. 对String类型的+操作实际上是通过创建并操作StringBuilder对象实现的,所以,当使用+处理的字符串比较复杂时,就应该选择创建StringBuilder对象,再使用StringBuilder中所提供的丰富的方法完成字符串的构建;
5. 在没有引入StringBuilder之前,Java使用的是StringBuffer,StringBuffer是线程安全的,因此开销大于StringBuilder,也就是说,使用StringBuilder速度更快。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android之获取手机上的图片和视频缩略图thumbnails
- android string.xml文件中的整型和string型代替
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序