zoukankan      html  css  js  c++  java
  • Java字符串里的 ==

    
          String str1 = "abc";
          String str2 = "abc";
          String str3 = "a" + "bc";       
    
          System.out.println(str1 == str2);
          System.out.println(str1 == "a" + "bc");
          System.out.println(str1 == new String("abc"));      
    System.out.println(new String("ab")+"c" == new String("ab")+"c");

    输出
    true
    true
    false
    false

    一般用来比较字符串是否相同的equals()是比较字符串的内容,即在堆中的字符序列。而 == 则是比较两个字符串的内存地址是否相同(堆中的引用)。

    第一个true很容易理解。str1和str2都是在内存的字符串常量池中。

    字符串常量池:

    • 为了减少在jvm中创建的字符串的数量,字符串类维护了一个字符串常量池,字符串常量池(String pool)是Java堆内存中一个特殊的存储区域;
    • 当创建String对象时,jvm会先检查字符串常量池,如果这个字符串的常量值已经存在在池中了,就直接返回池中对象的引用,如果不在池中,就会实例化一个字符串并放入池中;
    • 常量池:用于保存java在编译期就已经确定的,已经编译的class文件中的一份数据。包括了类、方法、接口中的常量,也包括字符串常量,如String s = "a"这种声明方式;
    第二个true:看上去“a"+"bc"是经过运算的,理应生成一个新的对象。但为什么它们却是相等的呢?这是因为“a"+"bc"这种只包含常量的字符串连接符创建字符串的也是常量。它们在编译器编译的时候就直接计算完成丢进了常量池里面。所以他们对应了同一个引用。
     
    三个False:
    第一个false很显然,使用了new就代表这个对象会存储在堆上。引用自然不会和在常量池中的对象一样。
     
    第二个false则是因为在运行期"ab"+"c"操作实际上是编译器创建了StringBuilder对象进行了append操作后通过toString()返回了一个字符串对象存在heap上。
     
    更多例子:
    String s0 = "111";              //pool
    String s1 = new String("111");  //heap
    final String s2 = "111";        //pool 
    String s3 = "sss111";           //pool
    String s4 = "sss" + "111";      //pool
    String s5 = "sss" + s0;         //heap 
    String s6 = "sss" + s1;         //heap
    String s7 = "sss" + s2;         //pool
    String s8 = "sss" + s0;         //heap
     
    System.out.println(s3 == s4);   //true
    System.out.println(s3 == s5);   //false
    System.out.println(s3 == s6);   //false
    System.out.println(s3 == s7);   //true
    System.out.println(s5 == s6);   //false
    System.out.println(s5 == s8);   //false
    对于final String s2 = "111",是一个用final修饰的变量,在编译期就已知了,在包含变量的字符串连接符"a"+s2时直接用常量"111"来代替s2,等效于"a"+"111",在编译期就已经生产了字符串对象"a111"对象在常量池中。


    参考:
    https://www.jianshu.com/p/039d6df30fea

     
     
  • 相关阅读:
    生成实用包装码
    区分排序函数
    mysql优化
    高并发、大流量、大存储
    数据库的搬移
    linux查看系统日志及具体服务日志
    springboot拦截器实现
    使用ajax的get请求渲染html
    百度echarts折线图使用示例
    前端特殊符号转码
  • 原文地址:https://www.cnblogs.com/Nullc/p/12692837.html
Copyright © 2011-2022 走看看