String类的两种实例化方式的使用与区别

String类实例化有两种方式:

  1. 通过直接赋值的形式为String类对象实例化
package com.yao.test;

public class StringTest {
    public static void main(String[] args) {
        String str= "hello word";
        System.out.println(str);
    }
}

运行结果:hello word

  1. 通过构造方法实例化String类对象
package com.yao.test;

public class StringTest {
    public static void main(String[] args) {
        String str = new String("hello word");
        System.out.println(str);
    }
}

运行结果:hello word

可以发现,两种方式得到的结果是相同的。但是,两者之间是有本质区别的,下面我们来分析一下:

  1. 当我们直接采用赋值方式实例化对象时,此时内存会开辟一块堆内存,内存空间将保存有"hello word" 字符串数据,并且栈内存将直接引用此堆内存空间,如下图所示:
    在这里插入图片描述
    当代码中使用了直接赋值的方式定义了一个String类对象时,会将此字符串对象所使用的匿名对象入池保存,如果后续还有其他String类对象也采用了直接赋值的方式,并且设置了同样的内容,那么将不会开辟新的堆内存,而是使用已有的对象进行引用分配,从而继续使用。我们可以看一个例子:
package com.yao.test;

public class StringTest {
    public static void main(String[] args) {
        String strA = "hello Java";
        String strB = "hello Java";
        String strC = "hello PHP";
        System.out.println(strA==strB);
        System.out.println(strA==strC);
    }
}
运行结果:	true
			false

可以看出,使用直接赋值实例化操作方式,而且内容相同,即使没有发生对象的引用操作,最终两个String对象(strA、strB)也都指向了同一块堆内存。

  1. 当我们使用构造方法实例化String对象时,因为每一个字符串都是一个String类的匿名对象,所以会首先在堆内存中开辟一块空间保存字符串"hello word",而后又使用new关键字开辟另一块堆内存空间,而真正使用的是用new关键字开辟的堆内存,而之前定义的字符串常量开辟的堆内存空间将不会被任何的栈内存所指向,成为垃圾空间,并等待被GC回收。所以,使用构造方法的方式开辟的字符串对象,实际上会开辟两块空间,其中一块空间将成为垃圾,如图所示:
    在这里插入图片描述

所以,当我们使用构造方式实例化String对象时,除了浪费内存外,还因为new关键字开辟新内存,从而导致其内容不会保存到对象池中。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值