简单的谈一下对String 的认识


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 区域。

  1.         String s1 = "abc";  
  2.         String s2 = "abc";  
  3.         String s3 = s1 + s2;  
  4.         String s4 = s3.intern(); 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值