关于创建String对象的抉择

来源:互联网 发布:天下霸图2 优化 编辑:程序博客网 时间:2024/06/01 08:13

关于创建String对象的抉择

标签(空格分隔): 与String有关的那些事儿
转自博客:java String 两种不同的赋值 比较


  • 关于创建String对象的抉择
    • 我的旧记忆
    • 新的认识
      • 类似普通对象通过new 创建字符串对象
      • 直接赋值
      • 手动入池
    • 国际惯例总结
    • 后话为什么String 可以直接赋值


我的旧记忆


之前我的大脑还是有概念的,只是比较模糊,我知道创建一个String对象有几种形式。

  • String string=new String()
  • String string=”jfirehj”

但是我是真不知道这两种形式有没有区别,因此在比较String 对象的时候,理解到不了位。

public class EmptyTest {    public static void main(String[] args) {        String s1 = "iiii";        String s2 = "iiii";        if(s1==s2){            System.out.println("you are right");        }        if (s1.equals(s2)) {            System.out.println("you are right again");        }    }}

输出是

you are right
you are right again

再来一次

public class EmptyTest {    public static void main(String[] args) {        String s1 = new String("iiii");        String s2 = new String("iiii");        if (s1 == s2) {            System.out.println("you are right");        }        if (s1.equals(s2)) {            System.out.println("you are right again");        }    }}

输出:

you are right again

使用new是在堆上创建了两个不同的对象。但是这个字符串创建的怎么来进行解释呢?


新的认识


找到的两篇写得比较好的博文:
第一篇
第二篇

原来就还有一个常量池的概念。

类似普通对象,通过new 创建字符串对象


String str = new String(“Hello”); 内存图如下图所示,系统会先创建一个匿名对象”Hello”存入堆内存(我们暂且叫它A),然后new关键字会在堆内存中又开辟一块新的空间,然后把”Hello”存进去,并且把地址返回给栈内存中的str, 此时A对象成为了一个垃圾对象,因为它没有被任何栈中的变量指向,会被GC自动回收
此处输入图片的描述

直接赋值

如String str = “Hello”; 首先会去缓冲池中找有没有一个”Hello”对象,如果没有,则新建一个,并且入池,所以此种赋值有一个好处,下次如果还有String对象也用直接赋值方式定义为“Hello”, 则不需要开辟新的堆空间,而仍然指向这个池中的”Hello”,原来如此
此处输入图片的描述

这段代码证明结论:
此处输入图片的描述

手动入池

即使使用new关键字,第一种方式赋值,也可以使用一个java中的手动入池指令,让所创建的对象入池,以后依然可以背重复使用,利用下面两段代码可以测试, 如下图,结果显然是false,因为二者的地址不同。

此处输入图片的描述

国际惯例:总结

通过常量池的形式可以很好的提高效率,因此提倡直接赋值

后话:为什么String 可以直接赋值

打开了String.class,有这么一段介绍:

/** * The <code>String</code> class represents character strings. All  * string literals in Java programs, such as <code>"abc"</code>, are  * implemented as instances of this class.  * <p>  * Strings are constant; their values cannot be changed after they  * are created. String buffers support mutable strings.  * Because String objects are immutable they can be shared. For example:  * <p><blockquote><pre>  *     String str = "abc";  * </pre></blockquote><p>  * is equivalent to:  * <p><blockquote><pre>  *     char data[] = {'a', 'b', 'c'};  *     String str = new String(data);  * </pre></blockquote><p>  * Here are some more examples of how strings can be used:  * <p><blockquote><pre>  *     System.out.println("abc");  *     String cde = "cde";  *     System.out.println("abc" + cde);  *     String c = "abc".substring(2,3);  *     String d = cde.substring(1, 2);  * </pre></blockquote>  * <p>  */  

通过上面的介绍,我们可以清楚,直接赋值的话,是通过编译器在起作用,当你对”abc”没有通过new创建时,他会自动默认给你调用构造函数new String(char value[]). 不显式调用String的构造函数(通过new叫显式调用),其实JDK编译器会自动给你加上。

编译器主动调用构造方法的情况出现很多次了也

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 西安华润万家预付卡丢了怎么办 租房签了一年合同想走怎么办 京东寄包裹在速递易里面该怎么办 翼码科技辅助码被删掉了怎么办 用别人的身份证注册的手机号怎么办 大v线做到假线了怎么办 有个摄像头网段不同搜不到怎么办 百度网盘离线下载有违规内容怎么办 抖音上传的照片与音乐不同步怎么办 社保卡里面的钱用完了怎么办 医保卡里面的钱用完了怎么办 手机通知栏变成了搜索栏怎么办 小米手机账号密码忘了手机号怎么办 暑假工没签合同押工资了的怎么办 在日本雅虎拍卖网站买到假货怎么办 没有百度糯米账号但是买票了怎么办 拼多多商家版登陆密码忘记了怎么办 安卓下载的软件闪退怎么办 老司机影视院开通会员看不了怎么办 梦幻西游手游苹果手机打不开怎么办 拼多多笔订单被判定虚假发货怎么办 苹果手机微信接收不到信息怎么办 内衣穿32太小穿34空杯怎么办 楼下的把下水管道堵死了怎么办?? 微信绑定的手机号码已停机怎么办 绑定微信的手机号停机了怎么办验证 绑定手机停机微信怎么验证码怎么办 五菱之光雨刷开关手柄断了怎么办 快手家长控制模式密码忘了怎么办 有陌生人要求你拉他入群怎么办 手机一天接到多个陌生电话怎么办 阳光惠生活登录密码忘了怎么办 一个身份证注册了两个支付宝怎么办 买手办拆了发现坏了怎么办 六个月宝宝喝贝因美过敏怎么办 超市盘点少的货扣员工工资怎么办 孩子东西在学校被偷了怎么办 想退出却不舍的感情不知怎么办? 我被老板摸全身失眠有阴影怎么办 不知道绑定支付宝的微博账号怎么办 银行卡丢了补办后支付宝账户怎么办