String

写一篇String的blog,算是自己的笔记
public class StringTest {
public static void main(String[] args) {
/*
* 这句在编译的时候就在常量池确定了Hello字符串对象,
* 之后在运行时会通过ldc指令在常量池分配“Hello”字
* 符串对象并将引用压入操作数栈 (注意这里在常量池分
* 配的是String对象,不要认为char数组)
*/
String s1 = "Hello";

/*
* 这一步并没有在编译的时候就在常量池确定了
* HelloWorld字符串(这个要注意) 通过字节码可以看见
* ,他会new一个StringBuilder对象,然后
* 在常量池分配World字符串对象,然后调用
* StringBuilder的append方法生成具有
* HelloWorld字符数组的StringBuilder
* 最后调用toString返回HelloWorld字符
* 串对象的引用,通过 看StringBuilder的
* toString 实现(return new String
* (value, 0, count))就可以看见返回的
* 对象是new出来的,所以此时s1指向的堆中
* 的String对象,当然常量池一定也有
* HelloWorld字符串对象
*
* 到这一步,常量池中会有Hello字符串对象
* 和HelloWorld字符 串对象,而s1指向的
* 是堆中的HelloWorld字符串对象
*/
s1 = s1 + "World";

/*
* 这里s2会指向常量池中早已经创建好的对象
* 常量池中不会重复创建含有相同字符序列的对象
*/
String s2 = "HelloWorld";

// 所以很明显这里的s1和s2指向的分别是堆中的对象和常量池中的对象
System.out.println(s1 == s2); // 打印false
// 当然里面的字符串字面值是一样的
System.out.println(s1.equals(s2));// 打印true

String s3 = new String("HelloWorld");

/*
* 这里的s3当然也会在堆中创建字符串对象,
* 当然常量池中已经有HelloWorld对象,
* 所以此时不会再在常量池创建
*/

/*
* 既然是new出来的新的东东, 所以当然和s1不同了,返回false
*/
System.out.println(s1 == s3);

}
/*当然类似这样的写法会在编译的时候就确定了hello world在常量池中
0 ldc <String "hello world"> [55]
2 astore_1 [s]
3 return
*/
void m2() {
String s = "hello" + " " + "world";
}


}

像这种问题面试的时候经常会出现,只有搞清楚原理才能够保证类似的问题绝对不会出错,而且可以说的很详细,还有比如类似String s = new String("HelloWorld")这种代码绝对没有必要写,特别是在多次循环中,非常浪费,还有类似字符串累加不要太多
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值