Java String相加底层原理分析
作者:LililililililMeng
Java String相加底层原理
代码
String a = "a"; String b = "b"; String c = "c"; String s1 = "a"+"b"+"c"; String s2 = a+b+c; System.out.println(s2==s1); System.out.println(System.identityHashCode(s1)); System.out.println(System.identityHashCode(s2));
粗略解释
首先了解字符串常量池,创建字符串对象分别有两种,一种是字面值创建,一种是 new 创建,这两者存储的内存地址是不一样的。
如果是字面值创建的方式,如 String a="a",JVM会先去字符串常量池中寻找有没有“a”这个字符串,若有,则将其地址给 a;若没有,则先在常量池里创建“a”,然后再把地址给a;而通过 new a = new String("a")的方式创建对象,则是在堆中创建“a”对象,a 指向这个对象。
当字符串进行拼接时,如果是字面值进行拼接,在编译阶段会进行优化,直接变成字符串”abc“。
当字符串变量相加时,因被final修饰,字符串不能修改,会 先生成StringBuilder对象,通过append()方法进行字符串拼接,在调用toString()方法形成新的字符串,所以s1可以理解为
StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("a"); stringBuilder.append("b"); stringBuilder.append("c"); String s = stringBuilder.toString();
上好的String 相加
//底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 //底层底层底层底层底层底层底层底层底层底层底层底层底层底层 return new String(result, 0, len + resultOffset);
两个String 对象相加,底层先生成一个StringBulider 对象,然后对两个字符串进行append,最后调用StringBuilder的toString方法进行返回 新的String对象 return new String()
String a="a"; String b="b"; String c=a+b; String d=new String("ab"); System.out.println(a+b==c); //false System.out.println((a+b).equals(c)); //ture
调用equals方法时候,String重写了equals ,比较的是String的值, 而==比较的是引用的地址的值,所以只要a+b一次就会返回一个新的String对象
看一个新的方法类似
public static boolean isAdmin(String userId){ return userId.toLowerCase()=="admin"; } public static void main(String[] args){ System.out.println(isAdmin("Admin")); }
以上代码返回false 还是一样底层上面方法返回 new String()
注意注意注意
String test="javaandpython"; String str1="java"; String str2="and"; String str3="python"; System. out. println(test=="java"+"and"+"python"); System. out. println(test ==str1 + str2 + str3);
第一个true 第二个false就不讲了,第一个由于是字符串字面量进行+操作,编译阶段直接有一个 javaandpython的字符串再常量池中,而不是通过StringBuilder.
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。