您的位置:首页 > 其它

简单的谈一下对String 的认识

2012-07-23 17:16 197 查看
String 在JAVA 世界里很重要也很特殊。所以呢,我结合网上众大侠的说法,按照我自己的理解整理了一下。

1.首先来加强几个概念的理解。

我们都知道,字符串字是一个由双引号括起来的字符序列,它是指向一个String实例的引用。 注意两层意思一个是字符序列,一个是引用。那么我们下面分别来解释下。

a.字符串常量池(String Literal Constant Pool),其中,Literal,就是字符串,数值等本身,不是引用,也不是别名。

来看JVM 如何来处理的:

虚拟机必须为每个被装载的类型维护一个常量池。

常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和floating point常量)和对其他类型,字段和方法的符号引用。

对于String常量,它的值是在常量池中的。

而JVM中的常量池在内存当中是以表的形式存在的,对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,

注意:该表只存储文字字符串值,不存储符号引用。

b.String提供了方法Intern让我们把显示的调用来把String对象放入到literal pool里面并返回这个新的引用,到这里既有值,又有引用了,来看下面的例子

tring s = “abc”。对于“abc”,它首先是一个String literal,(对应第一点理解下)

它在创建之后,立即利用String的intern方法,首先查看是否已有这个literal了,如果有直接将引用返回s,

如果没有先装入到了Literal Pool,然后返回这个String 实例的引用给s。

c.new && double quotes

在Java语言里,“new”表达式是负责创建实例的,其中会调用构造器去对实例做初始化;

构造器自身的返回值类型是void,并不是“构造器返回了新创建的对象的引用”,而是new表达式的值是新创建的对象的引用。 

同样只有双引号,就会牵涉 String Literal,那么来看下面例子

new String("abc"),既有new 关键字;又有双引号。所以“abc”会调用literal的逻辑,new 肯定是创建新的对象。具体的过程就是,在编译的这段代码的时候

首先用literral 看String literal Constant pool 是否存在“abc”,有就用它来创建新对象并返回引用(这里没有将引用赋值给谁),

如果没有,就在String Literal Constant pool先创建一个“abc”,再用它来创建新对象,这个对象在heap上并返回引用(同上)。
2.Constant expression.

常量表达式,比如 "ab" + "cabc"会被当成literal,也就等同"abcabc"
3.编译时计算和运行时计算的区别,
String a ="a"; ;

String b = "b";

String c = "a"+"b";//Constant expression,编译时计算,同时这个表达式会被看做是string literal。

String d = a+b;//非Constant express,运行时计算,会创建新的对象,不会被看做是string literal。
4.垃圾回收 

GC是不会收集Literal Pool的。但是会收集没有intern的String 变量对象。对下面的例子,s3会被回收,s4就不会。
根据 JVM specification .由此我们推测,String Literal Constant Pool 处在Permanent generation space.被分配在 Method area 区域。

        String s1 = "abc";  

        String s2 = "abc";  

        String s3 = s1 + s2;  

        String s4 = s3.intern(); 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息