string中“+”号重载及intern方法

Java String底层原理深度解析:常量池、intern与字符串拼接机制 String是Java中最基础又最易被误解的核心类,其不可变性、内存布局与JVM常量池紧密耦合。理解String需从对象创建机制切入:字面量直接入常量池,new String()则在堆中分配,二者地址不同导致==比较为false;intern()方法在JDK7+后将对象引用登记至堆内常量池,彻底改变语义;而字符串拼接的三种路径(+、StringBuilder、concat)对应不同字节码实现与性能特征。这些原理直接影响GC压力、序列化体积、缓存Key一致性及安全风险。本文围绕真实高频误区展开,涵盖常量池定位 阅读详情

以下内容为thinking in java(p504-p509)总结:
java中没有运算符重载,但实际上“+”在java中实现了重载,一条语句中第一个”+“当且运算的一方为String对象时,是将另一方转化为字符串并将两个字符串拼接在一起,其实现是在编译时如果发现一条语句中第一个“+”一方为String对象,则创建一个stringbuilder对象,利用其append方法 ,最后toString转换为字符串返回。可以使用以下代码和javap命令验证。
javap是jdk自带的工具,实现反汇编,即将字节码文件转换为汇编语言。以下代码:

public class TestString{

    public  String concat() {

        String str = "";
         return str+"hello"+"world"+"java!"+this;

    }

    public static String concatenation (String str) {
        for (int i=0;i<6;i++) {
            str+=i+",";
        }
        return str;
    }
    public static String concatenation (StringBuilder sb) {
        for (int i=0;i<6;i++) {
            sb.append(i+",");
            //sb.append(",");
        }
        return sb.toString();
    }
    public static void main(String[] args) {

        String str = "";
        StringBuilder sb = new StringBuilder();
        concatenation(str);
        concatenation(sb);

    }
}

先将该java文件编译,再使用javap -c命令查看反编译代码,第一个方法反编译结果为:
public java.lang.String concat();
Code:
0: ldc #2; //String
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder.””:()V
10: aload_1
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6; //String hello
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7; //String world
21: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: ldc #8; //String java!
26: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
29: aload_0
30: invokevirtual #9; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
33: invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
36: areturn
发现第3:创建stringBuilder对象, 第7:初始化, 第11:开始调用append方法,添加对象,最后调用自身toString方法并返回。
我们发现一条语句中“+”一方第一次出现字符串对象,则会创建stringBuilder对象,那么编译器自动创建并转换和手动编码并转换有什么区别呢?以两个循环方法为例:
public static java.lang.String concatenation(java.lang.String);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 6
5: if_icmpge 38
8: new #3; //class java/lang/StringBuilder
11: dup
12: invokespecial #4; //Method java/lang/StringBuilder.””:()V
15: aload_0
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: iload_1
20: invokevirtual #11; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
23: ldc #12; //String ,
25: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: astore_0
32: iinc 1, 1
35: goto 2
38: aload_0
39: areturn
第5:进入循环,每次循环创建一个StringBuilder对象,初始化后append添加,并自动toString,将堆内存首地址值赋给str,最后返回。
而手动编码并转换的过程如下:
public static java.lang.String concatenation(java.lang.StringBuilder);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 6
5: if_icmpge 27
8: aload_0
9: iload_1
10: invokevirtual #11; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
13: pop
14: aload_0
15: ldc #12; //String ,
17: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: pop
21: iinc 1, 1
24: goto 2
27: aload_0
28: invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: areturn
每次循环,直接调用stringBuilder对象append方法,最后显示调用toString并返回。相对于手动使用stringBuilder来说,前者占用内存空间且效率低。要注意的是,当在手动使用stringBuilder时如果使用”+“连接字符串则会创建新的stringBuilder对象。
然后,再讲一下String的intern方法,当String对象调用intern方法时,如果该对象与字符串常量池对象比较,存在相等的情况(根据equals方法返回值),则将常量池中该对象返回,否则,该对象加入到常量池中,并返回该对象的引用。intern方法的作用主要在于节约内存。

AVL(Athena Vortex Lattice)如何编写与应用(一) 前两个是弦向的涡个数和以cos函数分布的间距参数(设为1即可)后两个可以在这里声明也可以写到后面的每一个section中,是展向的涡个数和以sin函数分布的间距参数。这个文件是用来建立飞机模型的文件,是一定要有的文件,其他的.run和.mass并不是必须要有的,甚至mass文件并没有看到有人在使用。Sref、Cref、Bref是飞机的参考面积参考弦长和参考的展长,我的理解就是所设计飞机的S,c,b这三个参数。———————————————以上是飞机的基本信息——————————————— 阅读详情

相关推荐

BAPI_OUTB_DELIVERY_CHANGE扩展指南:利用EXTENSION2与SMOD_V50B0001实现自定义字段更新

本文详细解析了如何利用BAPI_OUTB_DELIVERY_CHANGE的EXTENSION2参数与增强点SMOD_V50B0001,在不修改标准代码的前提下,安全、标准地更新SAP交货单的自定义字段。通过清晰的步骤指南和实战代码示例,帮助开发者掌握通过增强字段实现定制化业务需求的完整流程与调试技巧。

fanta的博客 451

c++类与对象5——运算符重载

1. 加号运算符重载 运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 加号运算符重载 作用:实现两个自定义数据类型相加的运算 两种重载方式: 1.成员函数重载+号 2.全局函数重载+号 #include <iostream> using namespace std; //加号运算符重载 class Person { public: //1...

qq_45923342的博客 629

MOSFET高频响应实战:如何用LTspice仿真内部电容效应(附模型文件)

本文深入解析MOSFET高频响应中的内部电容效应,通过LTspice仿真工具详细展示如何提取模型参数并优化高频特性。从栅极相关电容到结电容的物理本质,再到实战案例中的开关损耗分析和频率响应扫描,提供全面的设计优化方法,帮助工程师有效应对高速开关电路中的电容挑战。

weixin_33725722的博客 392

C++使用重载实现string类型操作

c++符号重载

a1461848339的博客 610

XMC1402调试实战:如何用20元的Jlink-OB搞定SWD连接(附DAVE 4.4.2配置)

本文详细介绍了如何使用成本仅20元的Jlink-OB调试器,成功连接并调试英飞凌XMC1402芯片的完整实战流程。内容涵盖从理解芯片启动模式、使用Memtool完成首次烧录与模式切换,到Jlink-OB驱动安装、连接验证,以及在DAVE 4.4.2中配置调试环境并解决常见问题的全步骤,为个人开发者提供了一套高性价比的SWD调试解决方案。

zz67890的博客 554

IT世界里的“国境线”(芯片与算法篇)

首先分析下概念,对于芯片,相信大家已经比较了解,就不做过多的解释。我们说一下算法,虽然算法是应用在IT领域,但我相信学数学的同学,特别是学习计算数学的,对算法应该更加熟悉。记得在本科课程中,专门有一门课叫做“算法设计”。从概念上来讲,算法指的是解决问题的方法和流程,是一段逻辑,一系列解决问题的清晰指令。或者更通俗一点来讲,算法是从A到B,所有可能的计算方式。 一、 芯片与算法的关系 芯片和算法并不是独立或者对立的两个个体。芯片本身就集成了算法。算法是一种逻辑概念,芯片是算法的一种表现形式,软件也是算法的

weixin_49664622的博客 7020

+加号运算符重载

1.1 如果想让自定义数据类型 进行+运算,那么就需要重载 + 运算符 1.2 在成员函数 或者 全局函数里 重写一个+运算符的函数 1.3 函数名 operator+ () {} 1.4 运算符重载 也可以提供多个版本 #include<iostream> #include<string> using namespace std; class Nick { public: Nick() {}; Nick(int a, int b):m_a(a), m_b(b) {}; /

Scarlett的博客 907

【AVRCP】规范精讲[19]: 媒体属性全解析,让你的蓝牙设备显示完整歌曲信息

AVRCP协议中的媒体属性是蓝牙音频设备传输歌曲元数据的关键,包含标题、艺术家、专辑等32位ID标识的键值对信息。规范要求字符串属性必须使用UTF-8编码,但乱码问题频发(如中文显示异常),主因是设备未遵循编码标准或使用GBK等非规范格式。常见问题包括信息不全(仅显示标题)、封面缺失(因带宽限制或格式不支持)及更新延迟(通知机制未启用)。解决方案包括强制UTF-8编码、优化封面大小(如300x300像素JPEG)、主动请求缺失属性。Android示例代码展示了通过广播接收器解析媒体属性的方法。

byte轻骑兵的技术小窝 1万+

C++学习(6)——友元和运算符重载

friend(友元)、友元函数、友元类、+号重载(-号类似)、++重载(--类似)、=号重载。

似末的博客 1418

把 ABAP SQL 窗口函数讲透:从 OVER 到 LEAD、RANK 与累计分析

ABAP SQL窗口函数在不丢失明细记录的前提下,为每行数据提供组内统计和排名功能。它通过OVER子句定义计算窗口,支持三类函数:聚合型(AVG/SUM等)、排名型(ROW_NUMBER/RANK等)和取值型(LEAD/LAG)。相比GROUP BY会合并多行数据,窗口函数保留原始记录同时附加计算结果,特别适合需要保留明细又要展示统计信息的业务场景,如销售排名、客户分层分析等。语法核心是OVER子句,通过PARTITION BY分组,ORDER BY排序,可灵活定义计算范围。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1274

iStoreOS等软路由插件卸载的残留?分享一款软路由高级卸载工具,自定义卸载,轻松解决卸载残留问题

iStoreOS用户看过来!👀 还在被插件包残留困扰吗?本文分享一款“高级卸载”的插件,助你深度清理iStoreOS系统,彻底解决软件卸载不净的痛点,告别频繁恢复出厂设置的烦恼!🚀

XiaoqiangClub的博客 1551

C++运算符重载之加号运算符重载

总结2:不要滥用运算符重载,即你写的函数名是加法,可是函数的实现是减法,可以运行但是这叫滥用。总结1:对于内置的数据类型的表达式的的运算符是不可能改变的,即1+1=2不可变,不会为3.作用:实现两个自定义数据类型相加的运算。...

m0_72677702的博客 1920

自动分割和测量混凝土钢筋的思路与原理

该文提出了一种基于PCL库的点云处理系统,用于自动测量混凝土结构中钢筋的几何参数。系统采用多阶段处理流程:首先通过RANSAC算法提取地面并旋转对齐;接着使用区域生长算法分割混凝土结构;然后采用RANSAC线检测识别钢筋,按方向分类;最后通过圆柱拟合和坐标差计算获得钢筋间距、直径和高度差等参数。文章详细介绍了各模块的核心算法,包括地面检测、坐标变换、钢筋识别和几何计算等关键步骤,并分析了主要参数的敏感性。系统通过分层处理和坐标变换确保测量精度,为混凝土结构的无损检测提供了自动化解决方案。

weixin_45196569的博客 682

关于String的intern方法的讨论

引子 今天,同学发来一个关于String的程序段,让我判断,先给出代码,大家可先想想执行结果。 public class InternTest { public static void main(String[] args) { String s = new String("1"); s.intern(); String s2 = "1"; Syst

Quartzhao的专栏 827

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

String的内存和intern()方法

一、关于常量池 字符串在Java中用的非常得多,Jvm为了减少内存开销和提高性能,使用字符串常量池来进行优化。 在jdk1.7之前(不包括1.7),Java的常量池是在方法区的地方,方法区是一个运行时JVM管理的内存区域,是一个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态常量等。 运行时常量池是方法区的一部分。 来看一个图: (图片来自https://www...

weixin_30530523的博客 153

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

openjdk hotspot源码分析之string.intern方法原理

java实现引用的方式 java实现引用有直接指针和句柄池2种方式,下面简单说下2种方式的区别和优缺点: 1.直接指针的实现方式是把obj的内存地址或者相对偏移量直接赋值给Java变量,其优点是直接定位,访问快,但是缺点也很明显,Java是一门gc语言,当发生gc时,需要移动obj的偏移量,那么,对应的指针也需要发生移动,但是,由于直接指针实现的引用,指针是在Java的变量里的,移动是非常困难的 ...

qq_33678688的博客 635

深入理解Java String类

在Java语言了中,所有类似“ABC”的字面值,都是String类的实例;String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较、查找、截取、大小写转换等操作;Java语言为“+”连接符(字符串连接符)以及对象转换为字符串提供了特殊的支持,字符串对象可以使用“+”连接其他对象。

ifwinds的博客 20万+

String详解(intern、StringBuffer、StringBuilder)

“+”操作符,它执行的加入对原始类型(如int和double),重载对String对象进行操作。’+'两个字符串操作数进行串联。 java不考虑让开发者支持运算符重载。在支持运算符重载像C++语言,可以把一个“+”操作符来执行减法,引起不良代码。 “+”操作符是重载的内部支持字符串连接在java中的唯一操作符。注意到,“+”不在两个任意对象上工作。 字符串的方法 SN 方法 描述 1 char charAt(int index) 返回指定索引处的字符 2 int compareTo.

努力充实,远方可期 757

聊聊Java String.intern 背后你不知道的知识

导读:String.intern是一个JDK中的常用方法,通常用于缓存字符串,优化内存使用,然而频繁使用该方法也会导致别的问题,本文从该方法的实现入手,深入分析了可能出现...

weixin_45583158的博客 230

Java中String的intern方法,Java8常量池的位置,为什么String被设计为不可变,javap&cfr.jar反编译,javap反编译后二进制指令代码详解...

一个例子 public class TestString{ public static void main(String[] args){ String a = "a"; String b = a+"b"; String c = "ab"; String d = "a" +...

weixin_30323961的博客 83

java String字符串赋值及常量池原理、StringBuilder、StringBuffer

String字符串赋值及常量池原理 String简介 String设计为不可变类主要考虑到:效率和安全。 String常量池 由于String的不可变性,为了提高操作效率,所以设计常量池。从1.8开始,String常量池被放在了堆中,在1.8之前存放在方法区的运行时常量池。 String a = "a"做了什么 String a = "a" 这段代码首先 "a" 此字符串叫字符面值。在编译时,c...

mt23 913

String 源码学习笔记

String 源码学习笔记 对于java程序员来说,String类是在熟悉不过了,但你真的了解它吗?常用构造器有哪些?intern()方法是干什么的?字符串拼接“+”号是如何实现的?我们通过源码一一解答。 本章String源码使用java1.8版本 String以下几个特性决定它是不可变的 1、`String`是`final`类,不可继承。 2、字符数组成员变量`value`使用...

孙平平的博客 2990

深入理解Java String类(综合)

在Java语言了中,所有类似“ABC”的字面值,都是String类的实例;String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较、查找、截取、大小写转换等操作;Java语言为“+”连接符(字符串连接符)以及对象转换为字符串提供了特殊的支持,字符串对象可以使用“+”连接其他对象。String类的部分源码如下: public final class String ...

weixin_30532987的博客 84

String相关问题小结

1 String、StringBuffer、StringBuilder 的区别? 可变性: String 是不可变的。而StringBuilder 与 StringBuffer 都继承自AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 final 和 private 关键字修饰。AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。 线程安全性: String 中的对象是

ZkSky的博客 287

Java对String字符串对象的创建,管理和“+”运算符的实现

<br />Constant Pool常量池 的概念:<br /><br /> 在讲到String的一些特殊情况时,总会提到String Pool或者Constant Pool,但是我想很多人都不太<br /> 明白Constant Pool到底是个怎么样的东西,运行的时候存储在哪里,所以在这里先说一下Constant Pool的内容.<br /> String Pool是对应于在Constant Pool中存储String常量的区域.习惯称为String Pool,也有人称为<br /> Str

sun_abc的专栏 750

String s=new String("abc")创建了几个对象?

详细内容参考:http://www.cnblogs.com/ydpvictor/archive/2012/09/09/2677260.html  摘要: 1. 我们常用的创建一个类的实例(对象)的方法有以下两种: 一、使用new创建对象。例如String s2 = new String("abc"); 二、调用Class类的newInstance方法,利用反射机制创建对象。

courage的专栏 3065
上一篇: 线程状态及面试常见问题
下一篇: 包装类的自动装拆箱及Integer类的缓存区问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值