String对象的创建

String str = new String(“Hello“);创建了几个对象、String对象的创建面试题 面试题: 一、’ String str = new String("Hello");创建了几个对象? 这个主要分2种情况: 1、如果String的字符串常量池中有Hello这个对象,那么就只创建了一个对象。 原因:因为字符串常量池中有Hello,字符串会用已有的Hello对象,所有不会再创建Hello这个对象了,只会创建一个new String对象。 2、如果String的字符串常量池中没有He... 阅读详情

 

作者:Heart.Raid 

http://www.javaeye.com/topic/522167

每次上网冲杯Java时,都能看到关于String无休无止的争论。还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了。嘿嘿....


众所周知,String是由字符组成的串,在程序中使用频率很高。Java中的String是一个类,而并非基本数据类型。 不过她却不是普通的类哦!!!

 

【镜头1】 String对象的创建 
      1、关于类对象的创建,很普通的一种方式就是利用构造器,String类也不例外:String s=new String("Hello world"); 问题是参数"Hello world"是什么东西,也是字符串对象吗?莫非用字符串对象创建一个字符串对象?

      2、当然,String类对象还有一种大家都很喜欢的创建方式:String s="Hello world"; 但是有点怪呀,怎么与基本数据类型的赋值操作(int i=1)很像呀?

      在开始解释这些问题之前,我们先引入一些必要的知识:

★ Java class文件结构 和常量池 
      我们都知道,Java程序要运行,首先需要编译器将源代码文件编译成字节码文件(也就是.class文件)。然后在由JVM解释执行。
      class文件是8位字节的二进制流 。这些二进制流的涵义由一些紧凑的有意义的项 组成。比如class字节流中最开始的4个字节组成的项叫做魔数(magic),其意义在于分辨class文件(值为0xCAFEBABE)与非class文件。class字节流大致结构如下图左侧。

                                

      其中,在class文件中有一个非常重要的项——常量池 。这个常量池专门放置源代码中的符号信息(并且不同的符号信息放置在不同标志的常量表中)。如上图右侧是HelloWorld代码中的常量表(HelloWorld代码如下),其中有四个不同类型的常量表(四个不同的常量池入口)。关于常量池的具体细节,请参照我的博客《Class文件内容及常量池 》

public class HelloWorld{
void hello(){
System.out.println("Hello world");
}
}

          通过上图可见,代码中的"Hello world"字符串字面值被编译之后,可以清楚的看到存放在了class常量池中的字符串常量表中(上图右侧红框区域)。

     

    ★ JVM运行class文件

          源代码编译成class文件之后,JVM就要运行这个class文件。它首先会用类装载器加载进class文件。然后需要创建许多内存数据结构来存放class文件中的字节数据。比如class文件对应的类信息数据、常量池结构、方法中的二进制指令序列、类方法与字段的描述信息等等。当然,在运行的时候,还需要为方法创建栈帧等。这么多的内存结构当然需要管理,JVM会把这些东西都组织到几个“运行时数据区 ”中。这里面就有我们经常说的“方法区”、“堆 ”、“Java栈 ”等。详细请参见我的博客《Java 虚拟机体系结构 》 。

     

          上面我们提到了,在Java源代码中的每一个字面值字符串,都会在编译成class文件阶段,形成标志号 为8(CONSTANT_String_info)的常量表 。当JVM加载 class文件的时候,会为对应的常量池建立一个内存数据结构,并存放在方法区中。同时JVM会自动为CONSTANT_String_info常量表中 的字符串常量字面值 在堆中 创建 新的String对象(intern字符串 对象 ,又叫拘留字符串对象)。然后把CONSTANT_String_info常量表的入口地址转变成这个堆中String对象的直接地址(常量池解 析)。 

     

          这里很关键的就是这个拘留字符串对象 。源代码中所有相同字面值的字符串常量只可能建立唯一一个拘留字符串对象。 实际上JVM是通过一个记录了拘留字符串引用的内部数据结构来维持这一特性的。在Java程序中,可以调用String的intern()方法来使得一个常规字符串对象成为拘留字符串对象。我们会在后面介绍这个方法的。

     

    ★ 操作码助忆符指令 
          有了上面阐述的两个知识前提,下面我们将根据二进制指令来区别两种字符串对象的创建方式:  

          (1) String s=new String("Hello world");编译成class文件后的指令(在myeclipse中查看):

     

    0  new java.lang.String [15]  //在堆中分配一个String类对象的空间,并将该对象的地址堆入操作数栈。
    3  dup //复制操作数栈顶数据,并压入操作数栈。该指令使得操作数栈中有两个String对象的引用值。
    4  ldc <String "Hello world"> [17] //将常量池中的字符串常量"Hello world"指向的堆中拘留String对象的地址压入操作数栈
    6  invokespecial java.lang.String(java.lang.String) [19] //调用String的初始化方法,弹出操作数栈栈顶的两个对象地址,用拘留String对象的值初始化new指令创建的String对象,然后将这个对象的引用压入操作数栈
    9  astore_1 [s] // 弹出操作数栈顶数据存放在局部变量区的第一个位置上。此时存放的是new指令创建出的,已经被初始化的String对象的地址。

            事实上,在运行这段指令之前,JVM就已经为"Hello world"在堆中创建了一个拘留字符串( 值得注意的是:如果源程序中还有一个"Hello world"字符串常量,那么他们都对应了同一个堆中的拘留字符串)。然后用这个拘留字符串的值来初始化堆中用new指令创建出来的新的String对象,局部变量s实际上存储的是new出来的堆对象地址。 大家注意了,此时在JVM管理的堆中,有两个相同字符串值的String对象:一个是拘留字符串对象,一个是new新建的字符串对象。如果还有一条创建语句String s1=new String("Hello world");堆中有几个值为"Hello world"的字符串呢? 答案是3个,大家好好想想为什么吧!

       

            (2)将String s="Hello world";编译成class文件后的指令:

      0  ldc <String "Hello world"> [15]//将常量池中的字符串常量"Hello world"指向的堆中拘留String对象的地址压入操作数栈
      2  astore_1 [str] // 弹出操作数栈顶数据存放在局部变量区的第一个位置上。此时存放的是拘留字符串对象在堆中的地址

              和上面的创建指令有很大的不同,局部变量s存储的是早已创建好的拘留字符串的堆地址。 大家好好想想,如果还有一条穿件语句String s1="Hello word";此时堆中有几个值为"Hello world"的字符串呢?答案是1个。那么局部变量s与s1存储的地址是否相同呢?  呵呵, 这个你应该知道了吧。

         

         

        ★ 镜头总结: String类型脱光了其实也很普通。真正让她神秘的原因就在于CONSTANT_String_info常量表 和拘留字符串对象 的存在。现在我们可以解决江湖上的许多纷争了。

          【 纷争1】关于字符串相等关系的争论

        //代码1
        String sa=new String("Hello world");          
        String sb=new String("Hello world");    
        System.out.println(sa==sb);  // false     
        //代码2  
        String sc="Hello world";  
        String sd="Hello world";
        System.out.println(sc==sd);  // true 

                 代码1中局部变量sa,sb中存储的是JVM在堆中new出来的两个String对象的内存地址。虽然这两个String对象的值(char[]存放的字符序列)都是"Hello world"。 因此"=="比较的是两个不同的堆地址。代码2中局部变量sc,sd中存储的也是地址,但却都是常量池中"Hello world"指向的堆的唯一的那个拘留字符串对象的地址 。自然相等了。

            【纷争2】 字符串“+”操作的内幕

          //代码1
          String sa = "ab";                                        
          String sb = "cd";                                     
          String sab=sa+sb;                                    
          String s="abcd";
          System.out.println(sab==s); // false
          //代码2
          String sc="ab"+"cd";
          String sd="abcd";
          System.out.println(sc==sd); //true

                   代码1中局部变量sa,sb存储的是堆中两个拘留字符串对象的地址。而当执行sa+sb时,JVM首先会在堆中创建一个StringBuilder类,同时用sa指向的拘留字符串对象完成初始化,然后调用append方法完成对sb所指向的拘留字符串的合并操作,接着调用StringBuilder的toString()方法在堆中创建一个String对象,最后将刚生成的String对象的堆地址存放在局部变量sab中。而局部变量s存储的是常量池中"abcd"所对应的拘留字符串对象的地址。sab与s地址当然不一样了。这里要注意了,代码1的堆中实际上有五个字符串对象:三个拘留字符串对象、一个String对象和一个StringBuilder对象。
                  代码2中"ab"+"cd"会直接在编译期就合并成常量"abcd", 因此相同字面值常量"abcd"所对应的是同一个拘留字符串对象,自然地址也就相同。

             

             

             

            华为OD机试真题 新系统 - WIFI设备网络规划 (Java/Py/C/C++/Js/Go) 本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。 阅读详情

            相关推荐

            SAR成像系列:【3】合成孔径雷达(SAR)的二维回波信号与简单距离多普勒(RD)算法 (附matlab代码)

            二维回波信号分析

            zr2006_7的专栏 2万+

            面试官:String长度有限制吗?是多少?还好我看过

            GoKu编程toutiao.com/i6893014573322863111/前言话说Java中String是有长度限制的,听到这里很多人不禁要问,String还有长度限制?是的有,而且...

            程序员闪充宝 1242

            使用Gromacs进行蛋白和配体小分子的动力学模拟+结果分析全流程教程

            先选protein,选择non-water,使用pymol打开delWater.pdb,输入util.ss('all')展示cartoon,点击file-Export Moive as-MPEG。这一步完成后,文件夹中会出现以下三个文件,其中gro 文件用于记录蛋白的初始坐标,top 文件记录蛋白的拓扑信息和力场信息,itp 与top文件类似。接下来使用Spdbv软件打开蛋白,如果蛋白中存在原子缺失情况,就会出现以下的提示,如果不存在就不会显示,同时保存为rep.pdb。

            weixin_46587777的博客 2849

            面试官:String长度有限制吗?是多少?

            来源:toutiao.com/i6893014573322863111前言话说Java中String是有长度限制的,听到这里很多人不禁要问,String还有长度限制?是的有,而且在JVM编...

            Java团长的博客 533

            [HCTF 2018]WarmUp 1学习记录

            #[HCTF 2018]WarmUp 1学习笔记 最近做了做ctf,觉得真的很有趣,后悔当初没早点做,不过之前的学习也让我得到了不少经验基础,废话不多说,这次ctf虽然基本上靠了网上的大佬们(因为比较菜),但自己也做了些思考,应该对新手也比较友好吧。 ##1 首先怎么找源码,我承认我确实刚开始不知道在哪找,不过也很快找到了,相信也会有部分新手和我差不多吧 然后下面控制台会有个temp0,然后直接回车 后面我就受到启发,直接在链接后面加上source.php,进行页面跳转,然后就可以开始PHP代码审计了。

            weixin_45869407的博客 684

            【RT-DETR涨点改进】全网独家首发、特征融合改进篇 | AAAI 2026 | 引入CDEM交叉动态增强模块,双向引导和融合,在低光图像增强中有效提升了图像的亮度,提升小目标和暗目标的检测准确率

            本文提出了一种基于CDEM(交叉动态增强模块)改进的rtdetr网络模型,有效提升了在低光和复杂环境下的目标检测性能。CDEM模块通过动态增强亮度与色彩特征,改善图像输入质量,增强细节和对比度。该模块具有轻量级结构,易于集成到现有模型中,能够显著提升小目标和暗目标的检测准确率与鲁棒性。文章详细介绍了CDEM模块的结构原理、实现方法,并提供了完整的代码实现和配置指南,包括三种改进版本的YAML配置文件。实验结果表明,该方法在图像增强和目标检测任务中均取得了优异性能。

            Ai缝合怪、助力小伙伴高效发论文 142

            String长度限制

            编译期限制 String x = "abcd"; // 字面量 如果我们将 字符串 定义为字面量形式,编译时JVM会将其放入常量池中,这时候JVM对常量池存储String类型做出了限制。 常量池中,每个 cp_info 项的格式必须相同,它们都以一个表示 cp_info 类型的单字节 “tag”项开头。后面 info[]项的内容 由tag 的类型所决定。 String类型的表示是 CONSTANT_String ,我们来看下CONSTANT_String具体是如何定义的。 length=2^16-

            lq2440570330的专栏 432

            Error: Flash Download failed - Target DLL has been cancelled

            由于换了新电脑,keil重装了下,然而之前的MCU的支持包没有安装,以及一些其他的问题,导致可以编译但是不能将程序烧录到单片机中。现整理一下解决思路: 1、将支持包下载并添加: 找到你需要用的MCU的具体型号: 例如: 点击网址,下载安装包,或者在csdn等其他网址下载安装包,将下载好的pack包放到keil5的安装目录下的.Download中: 点击file中的import,将路径选择到.........

            hanhan的博客 5万+

            JVM-- String详解,JVM中的String

            String的基本特性 注意:String s2 = new String(“hello”)方式创建字符串,堆中存放值为hello的对象,同时会在字符串常量池中创建一个hello字符串常量 字符串常量池: 字符串常量池通过固定大小的Hashtable实现,通过Hash值类判断是否有相同字符串,如果这个大小值国小,就会导致有多个字符串具体相同的hash值,就会以链表的形式存放,如果链表过长就会导致效率变低。 StringTable具有GC操作。 如果设置的值不在指定范围内,就会报如下错误: Strin

            weixin_39724194的博客 1360

            图像处理 | 基于matlab的多尺度Retinex(MSR)和自适应直方图均衡化(CLAHE)算法联合的低照度图像增强(附代码)

            本文介绍了一种基于多尺度Retinex(MSR)和CLAHE的低照度图像增强算法。算法首先对图像进行多尺度Retinex处理,通过不同尺度的高斯核去除光照影响;然后采用CLAHE算法进行对比度增强。Matlab实现展示了算法流程,包含灰度转换、多尺度Retinex增强和CLAHE处理。实验结果显示,该方法能有效提升低照度图像的可见性,增强细节表现。最后提出了改进建议,包括引入深度学习方法和优化参数选择。

            尘世冰封的专栏 952

            uniApp微信小程序:error: 60001 request:fail errcode:-101 cronet error code:-101error_msg:net::ERR CONNECTI

            uni-app微信小程序域名访问报error 60001 request:fail errcode:-101,解决Uniapp微信小程序报600001错误,uni.request()接口请求报错,服务器更换SSL证书后,uniapp微信小程序出现`request:fail errcode:-101`问题分析与解决,服务器更换ssl证书后,手机访问微信小程序异常,微信小程序更换SSL证书后出现请求报错,服务器更换SSL证书,微信小程序报600001,小程序反应偶尔出现request:fail errcode:

            ✅ 精选推荐文章 4580

            String对象创建的方式

            字符串对象创建

            m0_60431736的博客 2306

            第14.10章 高翔博士最新开源框架Lightning-LM源码解读(十):在线定位run_loc_online涉及到的核心模块总结

            本文对Lightning-LM激光SLAM定位框架进行了全面剖析。该框架是一个轻量高效的激光雷达建图与定位系统,支持3D SLAM、动态图层管理等功能。文章首先介绍了项目概况和源码结构,包括核心模块如定位系统(loc_system)、激光匹配(lidar_loc)和位姿图优化(pose_graph)等。接着详细解析了各模块的关键函数和运行流程,如数据接收处理、NDT匹配和位姿优化等。最后总结了学习该框架所需的C++知识要点,包括智能指针、多线程编程等现代C++特性。该分析为SLAM开发者提供了实用的架构参考

            行知SLAM 801

            String创建了几个对象的问题

            情况一 String str1 = "hello"; 如果字符串常量池中不存在“hello”,创建1个对象,否则创建0个对象。 情况二 String str2 = "hello, " + "world"; 上面的代码会进行编译期优化,等价于String str1 = “hello, world”,与情况一 相同。 情况三 new String("hello); 如果字符串常量池中不存在"hello",创建2个对象,否则创建1个对象。 情况四 ...

            qq_43548662的博客 1212

            汉书HE8,好用的汇编代码编写工具

            汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

            华为的C语言编程规范.pdf

            华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

            关于String创建几个对象的问题

            今天去笔试一家外包公司,有这个一道笔试题,自己答错了,回来查看了一哈资料,分享一哈! 问:String s1="aa";        String s2="aa"; 这两段代码创建了几个对象?    本人回答的是3个。当时是这样想的:首先String s1="aa"  会先在常量区找aa,没有自己创建一个,这里就一个对象了;s1我也想当然的觉得是创建了一个对象,这就两个了;String s2

            Mos_wen的专栏 1326

            jre9下载 jdk9

            (Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

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

            一、java中String s = new String("abc")创建了几个对象 答案是两个,现在我们具体的说一下: String s = new String("abc"); 首先我们要明白两个概念,引用变量和对象,对象一般通过new在堆中创建,s只是一个引用变量。 所有的字符串都是String对象,由于字符串文字的大量使用,java中为了节省时间,在编译阶段,会把字符串文字放在文字池中...

            luzhensmart的专栏 1万+

            老版QQ原生表情gif动态

            这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

            String str=new String(“abc“);到底创建了几个String对象?

            String str=new String("abc")创建了2个String对象

            踏浪逐波 5827

            Java的String创建对象、String比较对象

            验证Java的String创建对象以及比较对象 public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); System.out.println("s1 == s2:-----:" + (s1 == s2)); S...

            qq_27243963的博客 1690

            JAVA创建String对象的问题

            最近在论坛上看到关于String s = new String("XYZ") + new String("XYZ");到底创建几个对象的讨论,觉得比较有意思,在此总结一下。在JAVA中除了8种基本类型之外,其他的都是类对象及其引用。所以 "XYZ"在JAVA中是一个String对象,对于String类对象来说它的对象值是不能修改的,也就是具有不变性。但是在下面一段程序中:public class TestString { public static void main(String args[])

            降龍 7377

            java string对象创建对象_Java String 创建了几个对象

            我们首先来看一段代码:Java代码String str=new String("abc");紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢?相信大家对这道题并不陌生,答案也是众所周知的,2个。接下来我们就从这道题展开,一起回顾一下与创建String对象相关的一些JAVA知识。我们可以把上面这行代码分成String str、=、"abc"和new String()...

            weixin_33334142的博客 378

            String详解,创建多少对象问题

            String详解,创建多少对象问题。

            jpkopkop的博客 3013

            java string对象创建对象_Java中String对象创建机制详解

            Java中String对象创建机制总是令人困惑,我会尝试阐述清楚这一机制。额,太粗心把 Stack 拼作 Strack 了,我会尽快把图片和文章校对好。1.创建方法1、 直接使用""双引号创建:String s1 = "first";2、 使用newString()创建:String s2 = new String();3、使用newString("string")创建 :String s3...

            weixin_28936649的博客 468

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

            答案是2个,大家肯定都知道。面试中经常出现的问题,今天认真分析一下。 1、 Sting s    定义了一个变量s,没有创建对象; 2、 =    赋值,将某个对象的引用(句柄)赋给s ,没有创建对象; 3、 “abc”    创建一个对象; 4、 new String() 创建一个对象。 首先,总结一下java创建对象的方式:new、clone、反射、反序列化 再看一下 St

            架构师思考实践 1万+

            String创建了几个对象

            我们首先来看一段代码: Java代码 String str=new String(“abc”); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢?相信大家对这道题并不陌生,答案也是众所周知的,2个。接下来我们就从这道题展开,一起回顾一下与创建String对象相关的一些JAVA知识。 我们可以把上面这行代码分成String str、=、"abc"和new String()四部分来看待。String str只是定义了一个名为str的String类型的变量,因此它并没有创建对象

            lucylala007的博客 2568

            Java中String对象创建

            字符串驻留 常量折叠 String a="abc"与String b=new String("abc")一样吗,难道也是语法糖??? String a="abc"要创建几个对象?? String a="abc";String b="abc";那么a==b吗?? String a="hello"+"world",创建几个对象?String b="hellowo

            wobushixiaobailian的博客 1096

            java创建String对象的问题

            最近在论坛上看到关于String s = new String("XYZ") + new String("XYZ");到底创建几个对象的讨论,觉得比较有意思,在此总结一下。   在JAVA中除了8种基本类型之外,其他的都是类对象及其引用。所以 "XYZ"在JAVA中是一个String对象,对于String类对象来说它的对象值是不能修改的,也就是具有不变性。   但是在下面一段程序中:

            移动开发 517
            上一篇: 内部类的学习
            下一篇: Java--数组
            QGJava
            博客等级 码龄16年 14粉丝 8原创
            评论 1
            成就一亿技术人!
            拼手气红包6.0元
            还能输入1000个字符
             
             条评论被折叠 查看
            添加红包

            请填写红包祝福语或标题

            个

            红包个数最小为10个

            元

            红包金额最低5元

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

            抵扣说明:

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

            余额充值