string类型和char类型的区别(string类型)
你们好,最近小时发现有诸多的小伙伴们对于string类型和char类型的区别,string类型这个问题都颇为感兴趣的,今天小活为大家梳理了下,一起往下看看吧。
1、 从何说起,我们先看看源代码,看看源代码对String类的解释:
2、 在java程序中,所有单词,比如“ABC”,都是String类的实例。
3、 字符串是常量,它们的值(注意是值)在创建后是不能更改的。
4、 Stringbuffer支持可变字符串。因为字符串类对象是不可变的,所以它们可以被共享。例如,String STR="ABC "和String STR=New String ("STR ")的值相等。
5、 Java语言提供了对字符串操作的特殊支持,它使用了StringBuilder类的append实现(下面将分析更详细的解释)。使用toString实现字符串转换。
6、 String类的修饰符是final,这意味着这个类不能被继承。重点是数据结构:字符数组。
7、 String类中有一个字符数组:private final char value[];可以看出,java字符串是以字符数组的形式实现的,并且是final,也就是说值是常量,它的值在确定之后是不可变的。
8、 同样如此,类似于StringBuilder中的append方法在String类中找不到。为了看得更清楚,
9、 看一下StringBuilder的值数组(在继承的抽象类AbstractStringBuilder中定义),char[]value;这是一个可变字符数组,没有最后的修饰。
10、 所以可以使用append方法追加一个字符串。
11、 接下来,看看它的equals方法,比较字符串是否相等。算法的核心也比较简单,就是从第一个位置开始比较,不一样就返回false,否则就比较下一个位置。
12、 HashCode也被重写了。如果两个字符串相等,则其hashCode的返回值是相同的。计算公式为:
13、 s[0]*31^(n-1) + s[1]*31^(n-2) + . + s[n-1]
14、 s是字符数组,n是它的长度。
15、 看完equals,我们再来看一个小程序,先写一个测试类。
16、 查看输出。首先要明确,equals是调用String类的方法,比较值数组的每一位是否相同,也就是比较变量引用对象的值。而“==”就是比较变量的引用是否相同。
17、 所以第一和第二的输出并不意外,这一点上面已经分析过了。
18、 关键是看第三和第四个输出:
19、 因为==比较的是引用的值而不是引用的值,所以意味着s1和s3指向同一个引用,而s2指向另一个引用。
20、 有两点需要强调:
21、 第一点,s1和s2的引用都是String对象,为什么这么说,因为可以通过反射拿到其所属的类java.lang.String。下图1
22、 第二点,也是比较关键的一点;到底创建了几个对象?如有异议欢迎指正。
23、 首先来看一眼jvm对String的管理:
24、 首先堆用于存储String类的实例;
25、 其次每一个jvm会维护一张内部表StringTable,用于存储程序运行时出现过的不重复的String对象的引用(不重复的判断方式equals)。
26、 常量池:存储字符串对象的引用。
27、 (1)String s1=“abc”,在StringTable中查找此字符串(使用hashCode和equals),如果有取其引用赋值给常量池;否则,创建一个字符串对象,
28、 并将其引用保存在常量池和StringTable中。在此例子中会在堆中创建一个对象A,然后将其引用存储到StringTable和常量池入口中。
29、 (1)String s2=new String(”abc“),new String每次都会在堆中创建一个新的对象B。检查StringTable中是否存在此字符串(使用hashCode和equals),
30、 没有的话再创建对象C,并将其引用保存在常量池和StingTable中。在此例子中首先会直接在堆中创建对象B;其次,在StringTable中已经发现了“abc”,所以不会购够再创建一个对墨劫称象了C,
31、 并且只会拿到A的引用去创建对象B,为何这么说,反编译的时候看到的(下图234,图4更说明了这一点,new的时候新的对象和原来的对象指向了同一个value数组)。并且最终s2指向的是对象B的引用。
32、 (3)String s3=“abc”,同理这句代码不会创建任何对象,只会将其入口指向s1的入口。
33、 所以最终是创建了两个对象A和B,常量池和StringTable存储的都是对象的引用。
34、 并且A和B的value数组其实是指向同一个地方,即共享一个final的字节数组,且看源码中的String构造方法,如下图4。
35、 在class文件的常量池中,未连接前,字符串变量直接指向的是字符串的值;
36、 连接后指向的是根据此字符串创建的对象的引用。
37、 字符串拼接操作:
38、 String a='ab';
39、 String b='cd';
40、 String c=a+b;//new String(value, 0, count);编译期不可确定,编译器不可优化,执行的时候借助stringBuilder。
41、 String d='abcd';
42、 String e='ab'+'cd';//编译器可以确定,编译器优化
43、 代码String c=a+b;是先创建一个StringBuilder,然后调用StringBuilder的append方法添加a和b,然后再调用其toString,在堆中new了一个对象,
44、 在new对象的时候,会检查常量池是否有“abcd”,有的话,对象的value数组,指向了常量池的引用对应的value的地址,而c则指向堆中的new的对象。
45、 代码String e='ab'+'cd';是直接在常量池生成一个字符串“abcd”,e指向常量池的“abcd”。
46、 下图是StringBuilder的toString,其创建了一个新的对象,并且会拷贝一份value数组。
47、 总结一点,如果字符串拼接的时候有变量,则会使用stringBuilder去处理。否则直接优化。
以上就是string类型这篇文章的一些介绍,希望对大家有所帮助。
免责声明:本文由用户上传,与本网站立场无关。财经信息仅供读者参考,并不构成投资建议。投资者据此操作,风险自担。 如有侵权请联系删除!
-
作为A股市场中极具代表性的黄金珠宝行业龙头企业,作为中国历史最悠久的珠宝品牌之一,老凤祥(股票代码:600612)...浏览全文>>
-
宝子们,杭州 房子装修完成啦!这次要给大家分享几家设计超赞的装修公司哦。它们各具特色,从空间规划到风格...浏览全文>>
-
欲筑室者,先治其基。在上海,装修房子对于每个业主而言,都是极为关键的一步,然而,如何挑选一家值得信赖的...浏览全文>>
-
2025年以来,联通支付严格贯彻落实国家战略部署,以数字和科技为驱动,做好金融五篇大文章,履行支付为民社会...浏览全文>>
-
良工巧匠,方能筑就华居;精雕细琢,方可打造美家。当我们谈论装修公司时,选择一家靠谱可靠的公司是至关重要...浏览全文>>
-
在当今社会,随着城市化进程的高速推进,建筑垃圾的产生量与日俱增。据权威数据显示,我国每年建筑垃圾产生量超 ...浏览全文>>
-
家人们,在上海要装修,选对公司那可太重要了!古语有云:"安得广厦千万间,大庇天下寒士俱欢颜。"一个温馨的...浏览全文>>
-
近年来,新能源汽车市场发展迅猛,各大品牌纷纷推出各具特色的车型以满足消费者多样化的需求。作为国内新能源...浏览全文>>
-
近年来,随着汽车市场的不断变化和消费者需求的升级,安徽滁州地区的宝来2025新款车型在市场上引起了广泛关注...浏览全文>>
-
随着汽车市场的不断变化,滁州地区的消费者对高尔夫车型的关注度持续上升。作为大众品牌旗下的经典车型,高尔...浏览全文>>
- 安徽滁州途安L新车报价2022款,最低售价16.68万起,入手正当时
- 小鹏G7试驾,新手必知的详细步骤
- 别克GL8预约试驾,4S店的贴心服务与流程
- 安徽阜阳ID.4 CROZZ落地价全解,买车必看的省钱秘籍
- 淮北探岳多少钱 2025款落地价,最低售价17.69万起现在该入手吗?
- 安徽淮南大众CC新款价格2025款多少钱能落地?
- 淮北长安启源C798价格,最低售价12.98万起现在该入手吗?
- 安徽淮南途锐价格,各配置车型售价全解析
- 蒙迪欧试驾预约,4S店体验全攻略
- 沃尔沃XC40试驾需要注意什么
- 滁州ID.4 X新车报价2025款,各车型售价大公开,性价比爆棚
- 试驾思域,快速操作,轻松体验驾驶乐趣
- 试驾长安CS35PLUS,一键搞定,开启豪华驾驶之旅
- 天津滨海ID.6 X落地价限时特惠,最低售价25.9888万起,错过不再有
- 天津滨海凌渡多少钱?看完这篇购车攻略再做决定
- 安徽池州长安猎手K50落地价,买车前的全方位指南
- 山东济南ID.6 CROZZ 2024新款价格,最低售价19.59万起,现车充足
- 试驾海狮05EV,新手必知的详细步骤
- 生活家PHEV多少钱 2025款落地价走势,近一个月最低售价63.98万起,性价比凸显
- 奇瑞风云A9试驾,新手必知的详细步骤