烧脑的java字符串比较(字符串常量池、指向堆、指向字符串常量池)--jdk1.8

本文是在jdk1.8的基础上解析的。

在JDK1.8中

调用 intern() 该方法:
如果常量池中 有 一个和当前对象相等 (用equals比较) 的字符串, 则返回常量池中的字符串 ;
否则把改字符串放到常量池中,并返回 该字符串的引用 .

一、实例解析1  

String str1=new String("he")+new String("llo");        //  在堆中产生三个对象,str1 只指向合并后生成的那个"hello"对象;
String str2="hello";                             //  在常量池中找,没有“hello”,所以在常量池中生成一个此常量对象,str2指向此对象,str2是常量对象的引用。
str1.intern();                                       //  在常量池中找,已经存在“hello”这个常量对象,故不生成常量引用.str1仍然指向堆中“hello”
System.out.println(str1==str2); // false                    //  两个对象的地址不一样,故false


String str1=new String("he")+new String("llo");       //  在堆中产生三个对象,string只指向合并后生成的那个"hello"对象;
 str1.intern();                                    //  在常量池中找,没有“hello”这个常量对象,所以把字符串放到常量池并返回这个常量字符串的引用,和堆中那个对象的地址相同
String str2="hello";                          //  常量池中已经存在这个常量对象的引用,所以str2指向这个引用,所以str2也指向str1对象  
System.out.println(str1==str2);// true                   //  地址一样,内容一样,所以true 
public static void main(String[] args)
{
    
String str1 = new String("1");
//首先此行代码创建了两个对象(如果常量池事先没有的话),在执行前会在常量池中创建一个"1"的对象引用,然后执行该行代码时 new 一个"1"的对象存放在堆区中;然后str1指向堆区中的对象;
   
str1.intern();
//因为常量池中已经有常量“1”,故不会生成引用(即不改变str1的指向,str1仍然指向堆中对象)。
   
String str2 = "1";
// str2 是常量池中“1”的引用。故str1和str2指向不同

System.out.println(str1 == str2);  //结果是 false 

}
public static void main(String[] args)
{
    String str1 = "aaa";
    String str2 = "bbb";
    String str3 = "aaabbb";
    String str4 = str1 + str2;
    String str5 = "aaa" + "bbb";
    System.out.println(str3 == str4); // false

    String ss = str4.intern();
    //如果常量池中 有 一个和当前对象相等 (用equals比较) 的字符串, 则返回常量池中的字符串,即使str4指向常量池中字符串的引用

    System.out.println(str3 == ss); // true
    System.out.println(str3 == str5);// true
}
public static void main(String[] args)
{
    Integer a = 1;
    Integer b = 2;
    Integer c = 3;
    Integer d = 3;
    Integer e = 321;
    Integer f = 321;
    Long g = 3L;

    System.out.println(c == d); //true
    System.out.println(e == f); //false
    System.out.println(c == (a + b));//true
    System.out.println(c.equals(a+b));//true

    System.out.println(g == (a + b));//true
    //包装类的“==”运行符在不遇到算术运算的情况下不会自动拆箱,
    // 以及他们的equals()方法不处理数据类型的关系,
    // 通俗的讲也就是 “==”两边如果有算术运算, 
    // 那么自动拆箱和进行数据类型转换处理,比较的是数值等不等。

    System.out.println(g.equals(a + b));//false
    // Long的equals方法会先判断是否是Long类型
}

 

 

 

 

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值