关于String字符串常量池的探讨

今天开始写博客,记录自己学习java道路上遇到的问题,也希望能够帮到各位看官。

下面看看今天讨论的问题:在使用String字符串时,初学者一般会混淆两种声明方式,即

String s1="abc";

String s2=new String("abc";);

那么这两种方式是否存在区别呢?我们来看一下代码

public class Test{
public static void main(String [] args ){
String s1="abc";
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");
System.out.println(s1==s2); //true
System.out.println(s1.equals(s2)); //true
System.out.println(s3==s4); //false
System.out.println(s3.equals(s4)); //true
System.out.println(s1==s3); //false
System.out.println(s1.equals(s3)); //true
}
}

有上述现象可以看出,两种方式得到的结果其实是不一样的,那么直接"="一个字符串(下文统称为字面量形式)和使用对象初始化的方式得到字符串到底有何不同呢?从而引出一个叫做字符串常量池的定义。

[b]JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池。当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。[/b]

所以,便可合理解释s1==s2为何为true了,原因就在于s1和s2均属于常量池中,但常量池中不允许出现重复的字符串,所以当s1在引用"abc"时,就将“abc”放入常量池中,当执行s2时,就直接将常量池中"abc"的引用赋值给s2,从而使得s1==s2的结果为true。

那么,我们来看一个面试常会被问道的问题,String str=new String("abc");会创建几个对象?我们可以通过javap -c Test来查看编译后的.class文件

[img]http://dl2.iteye.com/upload/attachment/0121/4455/e242ead8-e84b-3ae6-b50d-af7988015709.png[/img]

[quote]ldc 将int, float或String型常量值从常量池中推送至栈顶
new 创建一个对象,并将其引用值压入栈顶
dup 复制栈顶数值并将复制值压入栈顶
invokespecial 调用超类构造方法,实例初始化方法,私有方法
astore_1 将栈顶引用型数值存入第二个本地变量[/quote]

可以清楚看出,只使用new创建了一个对象。 :arrow:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值