全部博文(2065)
分类: Java
2010-03-20 19:43:20
Java中的String对象
[整理人:遥方 整理时间:
一、string是final
设计为final的原因可以参考:
第一,final修饰类表示不可被继承,final类的所有方法都是final的:这有两个好处:一是编译器会对final的方法进行内联的操作 (Think in JAVA中表示这不是必须的)提高运行效率;二是防止恶意用户修改String类的某些方法,如length()
第二,让一个类无法继承,表明这个类没有什么可以改进或扩充的啦,可能开发者认为这个类已经足够了,不需要用户进行特别的改进
第三,无从证实,有解释说如果String类不是final,可能会导致恶意用户修改系统System的参数,如访问控制权限,它的所有方法都是可以改变的,会导致不安全。
二、如何构建String对象
1. 首先String是个类,可以使用new直接创建:String s = new
String("hello");
这里发生的一切和其他一切对象的生成一样!
step 1:载入String的class文件,将相应类型信息放入方法区,此时字符串常量“hello”已经存入该语句所在类的常量池中
step 2:堆上创建一个String的引用对象s,将其压入栈中
step 3:寻找"hello"存储的位置
step4:调用new,按照String指定的构造函数创建对象,此时将"hello"传给了这个新生成的字符串对象
step5:将这个新生成的字符串对象的地址传给s
这个过程的指令集如下:
2.不同于一般的类,String还可以像基本类型那样进行初始化:String s = "hello";
这里的s直接存储的就是"hello"在堆中(常量池)的地址(s直接存的就是一个地址)
指令集如下:
有了上面两个介绍,其实大家就明白了,问题的关键就是String
s这个引用存储的是什么?是地址,是谁的地址?
三、相关的问题与解决
equals()比较的是值,==比较的是地址,请牢记
String sa = new String("hello");
String sb = new String("hello");
sa == sb;//false,sa和sb分别存放了两个字符串对象的引用及地址,肯定不同
String sa = "hello";
String sb = "hello";
sa == sb;//true,sa和sb存放的是字符串常量在常量池中的地址,是一样的
String sa = "hello "+"world";
String sb = "hello world";
sa == sb;//true,编译器会直接在编译时对字符串常量进行连接,因此sa和sb存储的是一样的,常量池中只有"hello world"
String s1 = "hello ";
String s2 = "world";
String sa = s1 + s2;//会由String转成StringBuilder之后再转成新string即类型会发生变化了!
String sb = "hello world";
sa == sb;//false,java程序运行时,对于字符串连接操作符‘+’,是将其转为StringBuilder()类或StringBuffer()类 的append()方法进行连接,相当于new了一个新的字符串对象
"a".toLowerCase()=="a";//对于字符串的操作如果结果不变,则会返回原来的字符串,所以相等
"a"+"b".toLowerCase()=="ab";//false,参考上例对'+'操作符在运行时的解释
心得:字符串在做 + 操作的时候是会变化其内在的字符对象的。得到出来一个新的对象值了。所以凡事做过+操作的其会生成出来一个新的对象出来!