new string(“abc”)创建了几个对象
我们再来通过两种写法分析:
String a = "123";
String b = new String("123");
如上第1行,定义了一个常量 a ,第2行,通过关键字 new 的形式,创建了一个变量 b 。
我们结合之前学过的 JVm 再深入一些,第1行在常量池开辟了一块空间,存放字符串 123,通过 a 对象指向这个常量对象。第2行由于使用了 new 关键字,所以会在堆空间中开辟一块内存区域,在其中存放字符串 123,并把内存的地址赋予 b 变量。
所以, a==b 吗?显示是 false,一个是堆内存,一个是常量池。
如果将 a 修改成:
String a = new String("123");
那么,a==b 吗?
依旧是 false。
为什么?只要通过 new 形式,自然是创建两个对象,所以是 false,即便是他们的值是一致的。
四、创建几个对象的练习
以下几种情况(均不考虑字符串在常量池中已存在的情况):
1、String a=“123”;
创建了1个对象
jvm在编译阶段会判断常量池中是否有 “123” 这个常量对象如果有,a直接指向这个常量的引用,如果没有会在常量池里创建这个常量对象。
2、String a=new String(“123”);
创建了2个对象
同情况1,jvm编译阶段判断常量池中 "123"存在与否,进而来判断是否创建常量对象,然后运行阶段通过new关键字在java heap创建String对象。
3、String a=“123”+“456”;
创建了1个对象
jvm编译阶段过编译器优化后会把字符串常量直接合并成"123456",所有创建对象时最多会在常量池中创建1个对象。
4、String a=“123”+new String(“456”);
创建了4个对象
常量池对象"123" ,“456”,new String(“456”)创建堆对象,还有一个堆对象"123456"。