String s=new String("123") 创建了两个对象,及证明

这个问题百度上有很多答案
有一次面试的时候,面试官也提到了这个问题。我回答了两个对象,并且解释了一个对象是 “123” 存在了字符串常量池,另一个是 s 所引用的堆中的对象。
但是面试官忽然来了一句,让我佐证一下。
我当时有点不知所措,又是扯hashcode,又是扯堆栈,感觉自己都没有回答出问题的关键。
不过现在我已经知道了

public class Test {
	public static void main(String[] args) {
		String s="123";
		String s2=new String("123");
		String intern = s2.intern();
		System.out.println(intern==s);//true
        System.out.println(s2==s);//false
    }
}

s2.intern 会返回字符串常量池中 等于堆中s值的引用 ,及s
所以intern是等于s的


--更新2019-10-5 ##java果然是越学越多,感觉自己就是个废物。 上面这个问题 其实就了更好的办法 先贴代码 ``` public class Test { public static void main(String[] args) { String ss=new String("123"); } } ``` 然后查看下编译好的class文件就ok了,我用的是idea的jclasslib插件 如图 ![](https://img2018.cnblogs.com/blog/1782870/201910/1782870-20191005140311234-56254684.png) 可以看到main方法被编译成了以下字节码 ``` 0 new #2 //new 创建对象 放在堆中 3 dup //dup 把new出来的对象的引用放入栈,这么是因为后面invokespecial 需要这个引用 去初始化,如果不入栈就找不到这个引用了。 4 ldc #3 <123> //Push item from run-time constant pool 放入运行常量池 6 invokespecial #4 > //初始化上面dup压入栈的引用 这里就是String 9 astore_1 //Store reference into local variable 10 return ``` 可以很清楚的看到 一个在堆,一个常量池
posted @ 2019-09-01 19:29  你还未发现  阅读(626)  评论(0编辑  收藏  举报