




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
String对象总结作者:zangxtString类是Java中很重要的一个类,在此总结一下这个类的特别之处。下面的相关资料翻译自java语言规范(第三版)和java虚拟机规范(第二版),有的直接摘引了原文。下面的代码都是用SUN jdk1.6 javac来编译。 1. String literal,这里将它翻译为字面常量,它由双引号包围的0个或多个字符组成,比如abc,Hello World等等。一个String字面常量总是引用相同的String实例,比如abc,abc两个常量引用的是同一个对象。 程序测试: 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; 另一个包: package other; public class Other static String hello = Hello; 输出: true true true true false true 结论有六点: 1) 同一个包下,同一个类中的相同的String字面常量表示对同一个String对象的引用。 2) 同一个包下,不同的类中的相同的String字面常量表示对同一个String对象的引用。 3) 不同包下,不同类中的相同String字面常量同样表示对同一个String对象的引用。 4) 通过常量表达式计算的String,计算在编译时进行,并将它作为String字面常量对待。 5) 通过连接操作得到的String(非常量表达式),连接操作是运行时进行的,会新创建对象,所以它们是不同的。 6) 显式的对一个计算得到的String调用intern操作,得到的结果是已经存在的相同内容的String字面常量。 补充说明: 1)像这样的问题,String str = a+b+c+d; 运行这条语句会产生几个String对象?1个。参考上面第5条,通过常量表达式得到的String 是编译时计算的,因此执行这句话时只有abcd着一个String对象存在。 常量表达是的定义可以参考java语言规范。另例: final String str1 = a; String str2 = str1+b; 执行第二句话会有几个String对象产生?1个。因为str1是常量,所以str1+b也是常 量表达式,在编译时计算。 遇到这种问题时,不要说它依赖于具体的编译器或者虚拟机实现,因为这就是规范里有的。一般的说,java的编译器实现应该遵守java语言规范,而java虚拟机实现应该遵守java虚拟机规范。2)不要这样使用字符串: String str = new String(abc); 参考文档中的说明: String public String(String original) 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。由于 String 是不可变的,所以无需使用此构造方法,除非需要 original 的显式副本。 参数: original - 一个 String。 注意:无需使用此构造方法! 3)单独的说明第6点: String str = new String(abc); str = ern(); 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。 很明显,在这个例子中abc引用的对象已经在字符串池中了,再调用intern返回的是已经存在池中内容为abc的字符换对象的引用。在上面的例子中也说明了这个问题。 2. String类的实例表示表示Unicode字符序列。String字面常量是指向String实例的引用。(字面 常量是“引用”!) 3.String转换 对于基本类型先转换为引用类型;引用类型调用toString()方法得到String,如果该引用类型为null,转换得到的字符串为null。 4. String链接操作“+” 如果“+”操作的结果不是编译期常量,将会隐式创建一个新的对象。为了提高性能,具体的实现可 以采用StringBuffer,StringBuilder类对多个部分进行连接,最后再转换为String,从而避免生成再丢弃中间的String对象。为了达到共享实例的目的,编译期常量总是“interned”的。 例子: String a = hello ; String b = a+1+2+world!; 反汇编结果: 0: ldc #2; /String hello 2: astore_1 3: new #3; /class java/lang/StringBuilder 6: dup 7: invokespecial #4; /Method java/lang/StringBuilder. :()V 10: aload_1 11:invokevirtual#5;/Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: iconst_1 15: invokevirtual #6; /Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 18: iconst_2 19: invokevirtual #6; /Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 22: ldc #7; /String world! 24: invokevirtual #5; /Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 27: invokevirtual #8; /Method java/lang/StringBuilder.toString:()Ljava/lang/String; 30: astore_2实际就是 String b = new StringBuilder().append(a).append(1).append(2).append(world).toString(); 这里就使用StringBuilder来避免中间临时String对象的产生而导致性能下降。 补充例子,下面的两个例子主要是对编译时常量做一个说明: 1) String c = c; String str = a+b+c; 和 2) String c = c; String str = c+a+b; 1)中,str=a+b+c;编译器分析是会把a+b作为编译时常量,生成字面常量ab,所以实际执行这句话时,链接的是ab和c。实际相当于执行了 String str = new StringBuilder().append(ab).append(c).toString(); 2)中,String str = c+a+b; 编译器分析到c为变量,后面的a+b就不会作为编译时常量来运算了。 实际运行时相当于执行 String str = new StringBuilder().append(c).append(a).append(b).toString(); 5.String对象的创建: 1) 包含String字面常量的类或者接口在加载时创建表示该字面常量的String对象。以下两种情况下不会创建新String对象。 a) 一个相同的字面常量已经出现过。 b) 一个相同内容的字符串已经调用了intern操作(比如经过运算产生的字符串调用intern的情形)。 2) 非常量表达式的字符串连接操作有时会产生表示结果的String对象。 3) String字面常量来自类或接口的二进制表示中(也就是class文件中)的CONSTANT_String_info 结构。CONSTANT_String_info结构给出了构成字符串字面常量的Unicode字符序列。 4) 为了生成字符串字面常量,java虚拟机检查 CONSTANT_String_info结构给出的字符序列: a) 如果与CONSTANT_String_info结构中给出的字符换内容相同的串实例已经调用过Sern,得到的字符串字面常量就来自该串的同一实例。 b) 否则,根据CONSTANT_String_info 中的字符序列创建一个新的字符串实例,然后调用intern方法。 例子:一个SCJP题目 11. public String makinStrings() 12. String s = “Fred”; 13. s = s + “47”; 14. s = s.substring(2, 5); 15. s = s.toUpperCase(); 16. return s.toString(); 17. How many String objects will be created when this method is invoked? 答案是3个。上面已经说明,Fred,47是字符串字面常量,它们在在类加载时创建的。这里题目问,方法调用时(!)有多少个String对象被创建,两个字面常量自然不包括在内。3个是:Fred47,ed4,ED4。 6.String与基本类型的包装类比较 相同点,它们都是不变类,使用=判断时可能会有类似的性质。 在java 5之后,java增加了自动装箱和拆箱功能。因此,就有了这样的性质: Integer i = 5; Integer j = 5; System.out.println(i = j); 结果:true. 这表面上看来是和String相同点,但其实现是极为不同的。这里作为一个不同点来介绍。 众所周知,自动装箱是这样实现的: Integer i = 5; 相当于 Integer i = Integer.valueOf(5);/注意不是new Integer(5),这就无法满足java语言规范中的约定了,约定见本文最后 而在Integer中,静态的创建了表示从-128+127之间数据的Integer对象,这个范围之内的数进行装箱操作,只要返回相应的对象即可。因此 Integer i = 5; Integer j = 5; 我们得到的是同一个对象。这是通过类库的设计来实现的。而String的共享是通过java虚拟机的直接支持来实现的,这是它们本质的不同。 这是Integer类中的部分代码: private static class IntegerCache private IntegerCache() static final Integer cache = new Integer-(-128) + 127 + 1; static for(int i = 0; i = -128 & i = 127) / must cache return IntegerCache.cachei + offset; return new Integer(i); 关于基本类型的装箱,Java语言规范中有如下说明: 如果被装箱的变量p为true,false,一个处于u0000u007f之间的byte/char,或一个处于-128+127之间的int/short,令r1和r2为对p的任何两个装箱操作的结果,则r1=r2总是成立的。理想的情况下,对一个基本类型变量执行装箱操作,应该总是得到一个相同的引用。但在实践中,在现存的技术条件下,这是不现实的。上面的规则是一个注重实效的折衷。 最后一点,要理解java的方法调用时的传参模型:java中只有pass by value。(不明
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025二级建造师考试题库及参考答案
- 江西省新余市2024-2025学年七年级下学期期末语文试题(解析版)
- 舞台技术工试题及答案
- 技术体系面试题及答案
- 2025年工具钳工(中级)考试试题题库
- 2025技术研发合同协议范本
- 2025新会计准则对保险业的影响及保险合同的完善
- 2025药品代加工合同模板
- 摄像机基础知识培训课件
- 搭配课件教学课件
- GB/T 17449-1998包装玻璃容器螺纹瓶口尺寸
- GB/T 12243-2021弹簧直接载荷式安全阀
- GB/T 10066.4-2004电热设备的试验方法第4部分:间接电阻炉
- PMC知识培训课件
- CJJ82-2019-园林绿化工程施工及验收规范
- 高中数学教材分析讲座课件第五章-三角函数
- 个人信息(模板)
- 会计师事务所验资工作底稿模板
- 婚育情况登记表
- (完整版)水电工安全技术交底
- 骨科学研究生复试真题汇总版
评论
0/150
提交评论