String类型的两种实例化区别

String类型有两种实例化的方法:
一种是直接赋值,如String str=“abc”;
另一种是通过new来实例化,如:String str=new String(“abc”);
通过一段测试代码,我们发现:

  public static void main(String[] args) {
        String str1="abc";
        String str2="abc";
        String str3=new String("abc");
        System.out.println(str1==str2);//true
        System.out.println(str1==str3);//false   
    }

结果运行如图:
在这里插入图片描述
为什么会这样呢?
原因是:String类型直接实例化与new实例化对象是不同的;
在字符串中“==”比较的是字符串的地址;equals比较的是字符串的内容;

如果采用直接赋值 法:
在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续引用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用;

如果采用构造方法new实例化一个对象:
该实例化对象却不会入池,且即使对象池中有该字符串内容,它也会直接开辟新的内存存放该字符串,不会引用池中的任何字符串,与池中的内容完全无关;

所以针对上面的代码:
String str1=“abc”; 因为是直接赋值,所以就将该字符串内容直接入池了;
String str2=“abc”;直接赋值,发现字符串对象池中有该字符串内容,所以直接引用了该字符串;导致str1与str2是指向的同一个字符串对象;
String str3=new String(“abc”);new实例化对象,直接开辟新的内存空间,与上面的两个字符串完全无关,

但是在String类中提供了方法入池操作 public String intern() ;
通过该方法,可以将用new实例化的字符串对象方入对象池中,其工作的过程就会和String直接赋值法工作的过程一样;

 public static void main(String[] args) {

        String str1="qwe";
        String str2=new String("qwe").intern();
        System.out.println(str1==str2);//true
    }

结果为:
在这里插入图片描述
且两种实例化对象的方式还有一点不同:
直接赋值法在实例化过程中只会创建一个堆内存空间:
如:String str=“Abc”;
在这里插入图片描述

在堆内存上创建一个字符串对象,使栈内存上的对象引用指向该字符串对象;

而通过构造方法实例化字符串对象的方法,在实例化过程中会创建两个堆内存空间:

如: String str=new String(“Abc”);
在这里插入图片描述
在实例化的过程中,首先会创建一个堆内存空间(1)存储字符串Abc,然后在new时,又创建了一个堆内存空间(2),存放该字符串对象,并使堆内存空间(1)成为垃圾空间,被回收,接着使栈里面的引用str指向该字符串对象;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值