有一道这样的程序:

 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. windows代码,路径分割

    BOOL SplitPathName( PWSTR MyXbpathBuffer, wstring& wdrive, wstring& wdir, wstring& wfnam ...

  2. 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    很多小伙伴没接触过Redis,以至于去学习的时候感觉云里雾里的,就有一种:教程随你出,懂了算我输的感觉. 每次听圈内人在谈论的时候总是插不上话,小编就偷偷去了解了一下,也算是初入门径. 然后就整理了一 ...

  3. 02. Install redis on Linux

    安装下载redis,参考官方文档:https://redis.io/download 下载: shell>wget http://download.redis.io/releases/redis ...

  4. Android App渗透测试工具drozer,Qark,Androguard

    一. drozer简介 drozer(以前称为Mercury)是一款Android安全测试框架. drozer允许您通过承担应用程序的角色并与Dalvik VM,其他应用程序的IPC端点和底层操作系统 ...

  5. Nginx下载服务器配置文件

    server { listen 8080; server_name localhost; #charset koi8-r; charset utf-8; #access_log logs/host.a ...

  6. 不一样的 SQL Server 日期格式化

    不一样的 SQL Server 日期格式化 Intro 最近统计一些数据,需要按天/按小时/按分钟来统计,涉及到一些日期的格式化,网上看了一些文章大部分都是使用 CONVERT 来转换的,SQL Se ...

  7. JournalNode failed to restart

    Install clusterEnable Namenode HAStart RU"Zookeeper" is completed"Core Masters" ...

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

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

  9. MVC添加Area出现“到多个与名为“Home”的控制器匹配的类型的解决方法”

    新建MVC项目,添加HomeController,然后添加名字为Admin的Area后,新建HomeController.这个时候,运行项目会出现以下错误: 解决办法如下: 打开网址下面的HomeCo ...

  10. Go基础(2)

    demo1: package main import ( "fmt" "strings" ) func main() { url := pathToUrl(&q ...