有一道这样的程序:

 public class TestStringDemo {

     public static void main(String[] args) {

         String s1 = "Programming";
         String s2 = new String("Programming");
         String s3 = "Program";
         String s4 = "ming";
         String s5 = "Program" + "ming";
         String s6 = s3 + s4;
         System.out.println(s1 == s2);
         System.out.println(s1 == s5);
         System.out.println(s1 ==     }
 }

让自己跟着做一遍,加深印象.....

程序的输出:

false
true
false

第一个输出:false ,我们还可以理解;

第二输出:true,跟我们的结果不一样,为什么输出true,不是说好了吗?字符串的+操作其本质是new了StringBuilder对象进行append操作,拼接后调用toString()返回String对象?

我们可以用以下命令获得.class文件对应的JVM字节码指令

javap -c StringEqualTest.class

JVM字节码指令:

第20~22行,我们通过对比知道,String s5 = "Program" + "ming";在被编译器优化成了String s5 = "Programming";

也可以得出字符串常量相加,不会用到StringBuilder对象,有一点要注意的是:字符串常量和字符串是不同的概念,字符串常量储存于方法区,而字符串储存于堆(heap)。

第三个输出:false ;通过以上的分析,自然也就明白了为森马是false了

我们来分析一下JVM字节码指令

  1. 第24行:使用new 了 StringBuider对象
  2. 第25行:进行StringBuider对象初始化
  3. 第26行:使用append() 方法拼接s3的内容
  4. 第27行:再使用append() 方法拼接s4的内容
  5. 第28行:最后调用toString() 返回String对象

总结:

  • 两个或者两个以上的字符串常量相加,在预编译的时候“+”会被优化,相当于把两个或者两个以上字符串常量自动合成一个字符串常量
  • 字符串的+操作其本质是new了StringBuilder对象进行append操作,拼接后调用toString()返回String对象  

Java中字符串相加和字符串常量相加区别的更多相关文章

  1. JAVA中令人疑惑的字符串

    Java中不同的字符串存在于同一个存储池中,字符串变量将指向存储池中相应的位置,也就是字符串变量里面包含的并不是字符串而是这个字符串对象的内存地址. String a = "123" ...

  2. Java中XML格式的字符串4读取方式的简单比较

    Java中XML格式的字符串4读取方式的简单比较 1.java自带的DOM解析. import java.io.StringReader; import javax.xml.parsers.Docum ...

  3. 使用java中replaceAll方法替换字符串中的反斜杠

    今天在项目中使用java中replaceAll方法将字符串中的反斜杠("\")替换成空字符串(""),结果出现如下的异常: java.util.regex.Pa ...

  4. Java中各种集合(字符串类)的线程安全性!!!

    Java中各种集合(字符串类)的线程安全性!!! 一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读 ...

  5. Java 中如何计算两个字符串时间之间的时间差?(单位为分钟)

    Java 中如何计算两个字符串时间之间的时间差?(单位为分钟) import java.text.DateFormat; import java.text.ParseException; import ...

  6. java中使用SimpleDateFormat实现字符串和日期的相互转换

    java中使用SimpleDateFormat实现字符串和日期的相互转换 import java.text.ParseException; import java.text.SimpleDateFor ...

  7. java中String new和直接赋值的区别

        Java中String new和直接赋值的区别     对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才 ...

  8. 【Java学习笔记之二十九】Java中的"equals"和"=="的用法及区别

    Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: String str1 = new String(" ...

  9. Java中equals()、equalsIgnoreCase()和==的区别

    用久了C#,在Java中,判断一个字符串还是习惯性的用了==,但是总是不能按照正确的判断分支运行,后来才想起来Java中是有equals的,然后就有引出了equalsIgnoreCase.   这三种 ...

  10. 【转】彻底弄懂Java中的equals()方法以及与"=="的区别

    彻底弄懂Java中的equals()方法以及与"=="的区别 一.问题描述:今天在用Java实现需求的时候,发现equals()和“==”的功能傻傻分不清,导致结果产生巨大的偏差. ...

随机推荐

  1. Centos 配置开机启动脚本启动 docker 容器

    Centos 配置开机启动脚本启动 docker 容器 Intro 我们的 Centos 服务器上部署了好多个 docker 容器,因故重启的时候就会导致还得手动去手动重启这些 docker 容器,为 ...

  2. Winform自定义无边框窗体

    目的: 1.将窗体设置成无边框,如下面效果图 2.该无边框窗体添加了窗体放大.缩小(可以根据需要只能横向放大缩小  或者  竖向放大缩小)的功能 Point vPoint = new Point((i ...

  3. 函数声明 和 var声明的优先级

    function demo() { console.log(5) } var demo = function(){ console.log(4) } console.log(demo()) var d ...

  4. 编译Xposed

    Xposed是Android平台上的有名的Hook工具,用它可以修改函数参数,函数返回值和类字段值等等,也可以用它来进行调试.Xposed有几个部分组成: 修改过的android_art,这个项目修改 ...

  5. #Java学习之路——基础阶段二(第四篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  6. java双重检测或枚举类实现线程安全单例(懒汉模式)

    双重检测实现 /** * 懒汉模式->双重同步锁单例模式 */ public class SingletonExample5 { private SingletonExample5() { } ...

  7. hadoop rpc协议客户端与服务端的交互流程

    尽管这里是hadoop的rpc服务,但是hadoop还是做到了一次连接仅有一次认证.具体的流程待我慢慢道来. 客户端:这里我们假设ConnectionId对应的Connection并不存在.在调用ge ...

  8. 【Python篇】---Python3.5在Centoos的安装教程--超实用

    一.前述 Python3在公司用的还是比较多的,但一般Centoos默认是python2的环境.所以本文就python3的安装做个总结. 二.具体 1.查看python版本python 命令即可 2. ...

  9. 一次 HashSet 所引起的并发问题

    背景 上午刚到公司,准备开始一天的摸鱼之旅时突然收到了一封监控中心的邮件. 心中暗道不好,因为监控系统从来不会告诉我应用完美无 bug,其实系统挺猥琐. 打开邮件一看,果然告知我有一个应用的线程池队列 ...

  10. KnockoutJS-绑定元素

    工作变更,又走回了WPF,一个来月没有接触web开发了,之前的KnockoutJS却不想放弃,继续进行知识的巩固,下个月开始重新走回web开发之路,还是得用回一些习惯了的工具.本次开始接触各绑定元素功 ...