java 基于JDK中的源码总结下String一
2013-03-29 21:50
295 查看
啰嗦下:发现自己的blog被转载了,不过没有注明出处,有点痛并快乐着的感觉。这里正式申明下:转载请注明出处,感谢。如有商用目的请务必知会本人。
挤出了一点时间根据JDK总结下String。源码开头的注释说明:String代表字符串,java中的所有字符串序列都是这个类型的实例。String是固定不变的,它们的值在分配之后就不可以改变。鉴于这一点它们的值可以用来共享。java语言对字符串连接运算符“+”提供了特别的支持,控制台输出的时候就经常用到+这个特性。再增加说明一点,String类私有的维护着一个string pool,这块存储区存放着全局唯一的字符串。说了一大堆,有点晕了,但是几个关键字要特别注意:固定不变,共享,对“+”运算符的特殊支持,string
pool。这几个关键词基本可以解释刚学java时候感觉到的String特殊性。
先说string pool,一般认为java中,基本数据类型和引用类型都存储在栈中,引用所指向的对象存储在堆中。String就很特殊,其在这两个区域之外还有一个私有的string pool。我们应该经常用到这一特性,但是很少有知道这一点的,sample:
第一句代码中str是引用类型,其指向string pool中的保存着"hello wolrd"的存储区。str1,str2也是引用类型,但是他们指向的类型在堆中,而不是string pool。str2更加特殊,String str2 = new String("the world"); 执行完之后实际上占用了两块内存,一块在堆中,一块在string pool中。事实上str1也有是一样的,但是变量str 前面已经在string pool中声明了一块区域,而string pool中的值是唯一的共享的,所以str1没有再一次分配内存。String
str2 = new String("……")这种声明每次会占用两块内存区域,在日常的编程中基本不用也就是由于这个原因。到这里string pool基本说完,可以告一段落。接着往下看说说字符串相等的比较,sample:
上面代码执行结束之后只会输出"str.equals(str1)",因为 == 运算符是基于地址进行的,而str指向string pool,str1指向堆,对象地址肯定不一样。 String类重新实现equals(Object anObject)方法,其是基于内容进行比较的。String源码中的说明如下:将此字符串与指定的object进行比较,只有当object不是null,并且是一个代表着同样的字符串序列的String对象才为真。再补充一个例子,sample:
这段代码会输出"sum.equals()" 和 "sum == "+""这两个字符串,原因前面已经说过,sum指向的是string pool中的内容,而sting pool中字符串唯一,所以地址和内容都相等。同样的原因,下面这段代码只会输出"sum1.equals()"
在上面的基础上接着说说intern()方法,这个也涉及到string pool,不过是没有新的知识。sample:
这段代码会输出"str.intern() == str1.intern()",看看源码中对intern()方法的说明:这个方法返回一个字符串的规范表示;String私有一个string pool 初始时为空;当这个方法被调用的时候,如果string pool中已经包含根据equals(Object)方法确定的和这个String想等的字符串,则直接返回这个字符串;否则这个字符串会被添加到string pool,并且返回它的引用;因此,对于任何两个字符串s和t,s.intern()== t.intern()当且仅当s.equals(t)为真的时候才为真。说到这里可以理解intern这个方法和equal基本等价。
今天先总结到这里。以上内容为自己总结,如果有错误还请指出,甚感。
挤出了一点时间根据JDK总结下String。源码开头的注释说明:String代表字符串,java中的所有字符串序列都是这个类型的实例。String是固定不变的,它们的值在分配之后就不可以改变。鉴于这一点它们的值可以用来共享。java语言对字符串连接运算符“+”提供了特别的支持,控制台输出的时候就经常用到+这个特性。再增加说明一点,String类私有的维护着一个string pool,这块存储区存放着全局唯一的字符串。说了一大堆,有点晕了,但是几个关键字要特别注意:固定不变,共享,对“+”运算符的特殊支持,string
pool。这几个关键词基本可以解释刚学java时候感觉到的String特殊性。
先说string pool,一般认为java中,基本数据类型和引用类型都存储在栈中,引用所指向的对象存储在堆中。String就很特殊,其在这两个区域之外还有一个私有的string pool。我们应该经常用到这一特性,但是很少有知道这一点的,sample:
String str = "hello world"; String str1 = new String("hello world"); String str2 = new String("the world");
第一句代码中str是引用类型,其指向string pool中的保存着"hello wolrd"的存储区。str1,str2也是引用类型,但是他们指向的类型在堆中,而不是string pool。str2更加特殊,String str2 = new String("the world"); 执行完之后实际上占用了两块内存,一块在堆中,一块在string pool中。事实上str1也有是一样的,但是变量str 前面已经在string pool中声明了一块区域,而string pool中的值是唯一的共享的,所以str1没有再一次分配内存。String
str2 = new String("……")这种声明每次会占用两块内存区域,在日常的编程中基本不用也就是由于这个原因。到这里string pool基本说完,可以告一段落。接着往下看说说字符串相等的比较,sample:
if(str == str1){ System.out.println("str == str1"); } if(str.equals(str1)){ System.out.println("str.equals(str1)"); }
上面代码执行结束之后只会输出"str.equals(str1)",因为 == 运算符是基于地址进行的,而str指向string pool,str1指向堆,对象地址肯定不一样。 String类重新实现equals(Object anObject)方法,其是基于内容进行比较的。String源码中的说明如下:将此字符串与指定的object进行比较,只有当object不是null,并且是一个代表着同样的字符串序列的String对象才为真。再补充一个例子,sample:
String sum = "+"; if(sum.equals("+")){ System.out.println("sum.equals("+")"); } if(sum == "+"){ System.out.println("sum == \"+\""); }
这段代码会输出"sum.equals()" 和 "sum == "+""这两个字符串,原因前面已经说过,sum指向的是string pool中的内容,而sting pool中字符串唯一,所以地址和内容都相等。同样的原因,下面这段代码只会输出"sum1.equals()"
String sum1 = new String("+"); if(sum1.equals("+")){ System.out.println("sum.equals("+")"); } if(sum1 == "+"){ System.out.println("sum == \"+\""); }
在上面的基础上接着说说intern()方法,这个也涉及到string pool,不过是没有新的知识。sample:
String str = "hello world"; String str1 = new String("hello world"); if(str.intern() == str1.intern()){ System.out.println("str.intern() == str1.intern()"); }
这段代码会输出"str.intern() == str1.intern()",看看源码中对intern()方法的说明:这个方法返回一个字符串的规范表示;String私有一个string pool 初始时为空;当这个方法被调用的时候,如果string pool中已经包含根据equals(Object)方法确定的和这个String想等的字符串,则直接返回这个字符串;否则这个字符串会被添加到string pool,并且返回它的引用;因此,对于任何两个字符串s和t,s.intern()== t.intern()当且仅当s.equals(t)为真的时候才为真。说到这里可以理解intern这个方法和equal基本等价。
今天先总结到这里。以上内容为自己总结,如果有错误还请指出,甚感。
相关文章推荐
- java 基于JDK中的源码总结下String
- java 基于JDK中的源码总结下String二
- java 基于JDK中的源码总结下String二
- Java Collections Framework之Collections源码分析(基于JDK1.6)
- JDK源码分析:java.lang.String
- Java String 源码浅析 JDK1.7
- JDK源码分析:java.lang.String
- JDK源码-java.lang.String
- java核心基础--jdk源码分析学习--String
- java的String学习加JDK源码的学习
- java.util源码之AbstractCollection(基于jdk1.7)
- Java Collections Framework之ArrayList源码分析(基于JDK1.6)
- Java -- 基于JDK1.8的LinkedList源码分析
- 从源码深入理解java集合(基于jdk1.7)
- Java Collections Framework之HashSet及LinkedHashSet源码分析(基于JDK1.6)
- Java集合框架成员之HashTable类的源码分析(基于JDK1.8版本)
- Java Collections Framework之Arrays(method:sort(),binarySearch(),copyOf())部分源码分析(基于JDK1.6)
- java读书笔记:ArrayList源码详解(基于jdk1.8)
- JAVA JDK API 源码学习 - Arrays.toString
- Java Collections Framework之LinkedList源码分析(基于JDK1.6)