基础--String类相关原理讲解
JVM内存模型
线程共享区域有:方法区,堆
线程私有区域有:虚拟机栈,本地方法栈,程序计数器。
具体每块区域上保存什么样的数据在图上已经标注了。
可以看到在方法区会保存运行时常量池,
所以String的常量池就存放在方法区上。
原理讲解
String a = "abc";
解释:
做此操作时,会先去常量池中寻找是否存在“abc”字符串,如果存在就直接将引用指向常亮池中存在的字符串,如果不存在,就在常量池中创建“abc”字符串。
String f = new String("123");
解释:
执行new操作,会在堆内存中创建新的对象。
String d = "123";
String e = "123";
String g = d + e;
解释:
执行字符串的拼接操作,其内部是执行原理是:先创建一个空的StringBuilder实例,然后执行append操作进行字符串的连接,然后调用toString方法返回一个字符串。
而toString方法的内部是执行的new String()操作,创建一个新的String实例,放在堆内存中。
创建StringBuilder实例,执行append方法等流程都可通过将代码进行javap操作看到。
StringBuilder的toString方法代码如下:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
常见的笔试题
String flag_one = "123";
String flag_two = new String("123");
String flag_three = "456";
String flag_four = "123456";
boolean a = flag_one == flag_two; //false
boolean b = flag_one.equals(flag_two); //true
boolean c = flag_one+flag_three == flag_four; //false
boolean d = flag_four.equals(flag_one+flag_three); //true
解释:
a: flag_one是存在于常量池中的,存在于方法区;flag_two是存在于堆内存中的;==操作是比较的两个实例的地址,所以为false。
b: equals操作是比较的值,所以返回true。
c: flag_one+flag_three做字符串的拼接操作,底层实际是创建的StringBuilder实例然后执行的appen方法进行字符串的拼接操作,最后调用的toString方法(new String())操作,所以还是存在于堆内存中。而flag_four是存在于方法去中的常量池中。比较两者的地址所以返回false。
d: equals方法比较两者的值,所以返回true。
加油共勉!!
本文地址:https://blog.csdn.net/weixin_42849706/article/details/109638914