java基础-String类Intern()方法分析

2020-08-05T16:44:51
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

1.==分析
Java中的对象默认都是Object类的子类,在Object中,equals方法与==都是比较地址(基本类型除外),下面看一段代码
public class Hello {

public static void main(String[] args) {
    String str = new String("abc");
    String str1 = "abc";
    String str2 = "abc";
    String str3 = "a"+"bc";
    String str4 = "a";
    String str5 = str4 + "bc";
    Integer num = 125;
    Integer num1 = 125;
    Integer num2 = 128;
    Integer num3 = 128;
    System.out.println(str1==str2);//true
    System.out.println(str==str1);//false
    System.out.println(str.intern()==str1);//true
    System.out.println(str==str.intern());//false
    System.out.println(str1==str3);//true
    System.out.println(str1==str5);//false
    System.out.println(num==num1);//true
    System.out.println(num2==num3);//false
}

}
2.分析上面结果
1.str1==str2为true 是因为在类编译时候,abc就存放于字符串常量池中,str1 和 str2指向的是同一个常量池的地址。
2.str==str1为false是因为通过new关键字后,str指向的是堆内存中的地址,而str1指向的是常量池中地址,所以地址不同。

3.str.intern()==str1为true是因为intern()方法返回的是常量池里面值的地址,如果常量池没有abc,那么先创建abc然后返回该常量池中的地址。注意String str = new String(“abc”);这段代码中,如果abc在之前没有定义,则创建了两个对象,str 和 abc。

4.str==str.intern()为false是因为str是指向堆中的地址,str.intern()指向常量池中地址。

5.str1==str3为true是因为str3=“a”+“bc”; 在常量池中创建了a 和 bc两个字面量值,通过+号拼接成abc,str3指向abc,str1也指向abc。

6.str1==str5为false是因为在编译时候,str5=str4 + “bc”;是通过对象StringBuilder拼接的,相当于在堆中创建了对象abc,str5指向它,而str1指向的是常量池中的地址。

7.num==num1为true是因为Integer维护了-128到127的常量值在方法区的常量池中,num 和num1指向的都是常量池中地址。

8.num2==num3为false是因为超过了127之后,Integer不是基本类型,相当于创建了num2 和 num3两个对象,地址不同。

3.我们再看一段代码
public class Hello {

public static void main(String[] args) {
    String buffer = new StringBuffer("abc").toString();
    String buffer1 = new StringBuffer("abc").append("de").toString();
    System.out.println(buffer.intern()==buffer);//false
    System.out.println(buffer1.intern()==buffer1);//true
}

}

结果为什么会这样呢?我们来分析下

String buffer = new StringBuffer(“abc”).toString();这段代码创建两个对象,首先是常量池中的abc,然后是buffer指向堆中地址,值任然是abc,所以buffer.intern()==buffer为false.
String buffer1 = new StringBuffer(“abc”).append(“de”).toString();首先在池中创建了abc 和 de然后通过append()方法拼接后变成abcde,buffer1指向堆中的字符串实例,intern()方法只是记录在常量池首次出现的实例的引用,因此buffer1.intern()发现常量池中没有该对象,于是把buffer的引用地址指向常量池,这时候常量池存储的是堆中地址的引用,和StringBuffer创建的那个字符串实例是同一个。

扫一扫关注公众号添加购物返利助手,领红包
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »
因本文不是用Markdown格式的编辑器书写的,转换的页面可能不符合MIP标准。