字符串拼接及创建的案例分析
案例一
String a = "test";
String b = "test";
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1639705018
- 当a初始化时,"test"对象被加入字符串常量池,b初始化时,检查到"test"对象在字符串常量池中,则直接指向该对象;
- a.equals(b)比较的是对象持有的内容,显然为true,a==b比较的是是否指向的是同一对象,因为指向的同为字符串常量池中"test"对象,结果为true;
- System.identityHashCode方法的返回值为参数对象object中hashCode()的返回值,无论hashCode()方法是否被覆盖。
案例二
String a = "test";
String b = new String("test");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1627674070
- 当a初始化时,"test"对象被加入字符串常量池,b初始化时,首先检查到"test"对象在字符串常量池中,无需在字符串常量池中创建对象,然后在堆中创建"test"对象,b指向堆中"test"对象;
- 可得a.equals(b)为true,a==b为false
案例三
String a = new String("test");
String b = new String("test");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1627674070
- 当a初始化时,"test"对象被加入字符串常量池,然后在堆中创建"test"对象,a指向堆中"test"对象;
- b初始化同a,但是不像字符串常量池中那样,虽然a与b的内容相同,但是依然会在堆上创建两个对象;
- 所以a.equals(b)为true,a==b为false
案例四
String a = "test";
String b = "te"+"st";
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1639705018
与案例一不同的是,b的值由两个引号相加所得,但是结果和案例一是一样的,a与b指向的都是字符串常量池中的同一对象,这是因为形如"te"+"st"这种由多个字符串常量连接而成的字符串在编译期被认为是一个字符串常量
案例五
String a = new String("test");
String b = new String("te") + new String("st");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1627674070
- 根据案例三中的分析可知,a与b内容是一致的,但是指向的不是同一对象,但是问题是这个案例中会在字符串常量池中创建多少个对象?
- 答案应该是三个:“test”、“te”、“st”;在堆上会创建多少个对象?答案是四个:a指向的"test"对象,两个匿名对象"te"、“st”,b指向的"test"对象
案例六
String a = "test";
String b = "te";
String c = "st";
String d = b + c;
System.out.println(a.equals(d)); // true
System.out.println(a == d); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(d)); // 1627674070
<