java中串池和小整数对象池

==和equals的区别

  • == 多用来比较基本类型的值是否相等,如果是引用类型的数据,使用==就是在比较它们的地址是否相同
  • equals方法是Object类提供得,由于其是所有引用类型的祖先,所以所有引用类型都具有equals方法
  • equals方法默认是返回两个对象的地址的比较结果,即 return o1 == o2;
  • 子类重写equals方法可以实现更为丰富的比较逻辑,可以是多个基本类型属性的==判断结果的逻辑运算结果,也可以结合引用类型属性的equals方法的逻辑结果进行逻辑运算,可以满足任何自定义的比较方法。

StringTable

StringTable:字符串常量池,也叫串池

  • 常量池依赖于equals方法,保证池中任何两个对象做equals的结果均为false, 即互不相同

  • 字符串常量池的存储结构类似于HashSet,分为多个桶来存放,虚拟机参数可以设置桶的值

  • 字符串可以调用intern方法,如果该字符串对象在常量池中,则返回对象自己的引用;如果不在常量池中,那么查看常量池中找到与其可以equals为真的对象并返回其引用。如果常量池中没有,则把自己加入到池中,并返回自己的对象引用。

  • 使用字面量写的字符串:“a”,”aaa”这些直接在字符串常量池中;而使用new String(“a”)这种不在字符串常量池中,可以使用itern() 方法使其入池;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Demo05 {
public static void main(String[] args) {
String s1 = new String("gt");
String s2 = new String("gt");
System.out.println(s1 == s2); // false

String s3 = "gt";
String s4 = "gt";
System.out.println(s3 == s4); // true
System.out.println(s3 == s1); // false

String s5 = "gtgt";
String s6 = s3 + s4;
System.out.println(s5 == s6); // false

// 两个常量相加直接放池子中,编译器替我们做了优化
final String s7 = "gt";
final String s8 = "gt";

// 直接编译成 String s9 = "gt" + "gt" ; -> String s9 = "gtgt";然后再运行
String s9 = s7 + s8;
System.out.println(s5 == s9); // true

// 有变量参与,编译器无法优化,底层是调用了StringBuilder的方法,new了String对象
final String s10 = s3 + s4;
System.out.println(s5 == s10); // false

// 使用intern可以使用字符串常量池中的对象,也可将对象入池
System.out.println("---------------------------------------");

String s11 = s10.intern();
System.out.println(s5 == s11); // true
System.out.println(s11 == s10); //false

String s12 = s1.intern();
System.out.println(s12 == s4); // true

String s13 = s6.intern();
System.out.println(s13 == s5); // true
}
}

小整数常量池

java中小整数对象池针对的是Integer对象,小整数对象池中对象数值属性的范围为 -128 - 127

  • new Integer(1); 这种对象不在常量池中。Integer i1 = 1;这样的范围符合的如此声明赋值的对象在常量池中
  • JDK1.5之后,基本类型的包装类可以自动装箱和拆箱,但需要一定条件,== 比较的时候,如果都是包装类,不会拆箱
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Demo06 {
public static void main(String[] args) {
Integer i1 = new Integer(12);
Integer i2 = new Integer(12);
System.out.println(i1 == i2); // false 不拆箱,比较地址
System.out.println(i1.equals(i2)); // true 比较的值
System.out.println(i1+0 == i2+0); // true 自动拆箱了

Integer i3 = 127;
Integer i4 = 127;
int i5 = 127;
System.out.println(i3 == i4); // true 常量池中只有一份
System.out.println(i3 == i5); // true 拆箱比较

Integer i6 = 128;
Integer i7 = 128;
int i8 = 128;
System.out.println(i6 == i7); // false 超出了范围,不在常量池中
System.out.println(i6 == i8); // true 拆箱比较
}
}

java中串池和小整数对象池
https://blog.wangxk.cc/2020/10/04/java中串池和小整数对象池/
作者
Mike
发布于
2020年10月4日
许可协议