当前位置: 首页 > news >正文

String 类型的变量和常量做 “+” 运算时发生了什么?

先看看字符串不加 final 关键字拼接的情况(jdk1.8):

String str1 = "str"
String str2 = "ing"
String str3 = "str" + "ing"
String str4 = str1 + str2
String str5 = "string"
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false

注意:比较 String 字符串的值是否相等,可以使用 equals() 方法。 String 中的 equals 方法是被重写过的。 Objectequals 方法是比较的对象的内存地址,而 Stringequals 方法比较的是字符串的值是否相等。

String str1 = "str"
String str2 = "ing"
String str3 = "str" + "ing" // 常量池中的对象
String str4 = str1 + str2 // 在堆上创建的新对象
String str5 = "string" // 常量池中的对象
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false

对于编译期可以确定值的字符串,也就是常量字符串,jvm 会将其存入到字符串常量池。并且字符串常量拼接得到的字符串常量在编译阶段就已经被存放到字符串常量池,这个得益于编译器的优化

在编译过程中,Javac编译器会进行一个叫做 常量折叠的代码 优化。常量折叠会把常量表达式的值求出来作为常量嵌在最终生成的代码中,这时 Javac 编译器对源代码做的极少量优化措施之一。

对于 String str3 = "str" + "ing" ; 编译器会将代码优化成 String str3 = "string"; 。

并不是所有的常量都会进行折叠,只有编译器在程序编译期就可以确定值的常量才可以:

  • 基本数据类型(bytebooleanshortcharintfloatlongdouble)以及字符串常量。
  • final 修饰的基本数据类型和字符串变量
  • 字符串通过 “+” 拼接得到的字符串、基本数据类型之间算术运算、基本数据类型的位运算。

引用的值在程序编译期间时无法确定的,编译器无法对其进行优化。

对象引用 和 “+” 的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到一个 String 对象。

String str4 = new StringBuilder().append(str1).append(str2).toString();

在平时写代码的时候,尽量避免多个字符串对象拼接,因为这样会重新创建对象。如果需要改变字符串的话,可以使用 StringBuilder 或者 StringBuffer 。

不过字符串使用 final 关键字声明之后,可以让编译器当做常量处理。

eg:

final String str1 = "str";
final String str2 = "ing";
// 下面两个表达式其实是等价的
String c = "str" + "ing";// 常量池中的对象
String d = str1 + str2; // 常量池中的对象
System.out.println(c == d);// true

被 final 关键字修饰后的 String 会被编译器当做常量处理,编译器在程序编译期就可以确定它的值,其效果相当于访问常量。

如果编译器在运行期才能确定它的值的话,就无法对其优化。

http://www.lryc.cn/news/183598.html

相关文章:

  • 【Java互联网技术】MinIO分布式文件存储服务
  • 在visual studio里配置Qt插件并运行Qt工程
  • 【C语言】利用数组处理批量数据(字符数组)
  • 算法通过村第十二关-字符串|白银笔记|经典面试题
  • 《视觉 SLAM 十四讲》V2 第 5 讲 相机与图像
  • 使用libmodbus库开发modbusTcp从站(支持多个主站连接)
  • GPT系列论文解读:GPT-2
  • (四)激光线扫描-光平面标定
  • 妙不可言的Python之旅----(二)
  • cartographer(1)-运行
  • C++:模板进阶与继承
  • vue-img-cutter 实现图片裁剪[vue 组件库]
  • 手把手教你从零开始腾讯云服务器部署(连接建站教程)
  • 微信开放平台第三方开发,实现代小程序备案申请
  • 设计模式——11. 享元模式
  • 【LLM】主流大模型体验(文心一言 科大讯飞 字节豆包 百川 阿里通义千问 商汤商量)
  • CSS小计
  • 机器学习:决策树
  • xxl-job的原理(2)—调度中心管理注册信息
  • 小白入门pytorch(二)----神经网络
  • 【进阶C语言】排序函数(qsort)与模拟实现(回调函数的实例)
  • CentOS 7 上编译和安装 SQLite 3.9.0
  • [GXYCTF2019]禁止套娃 无回显 RCE 过滤__FILE__ dirname等
  • Springboot使用Aop保存接口请求日志到mysql
  • 网络安全面试题汇总(附答案)
  • Centos7安装kvm,配置虚拟机网络
  • Javascript文件上传
  • golang gin——文件上传(单文件,多文件)
  • 面试题:Redis和MySQL的事务区别是什么?
  • Canvas绘图