(重要)字符串编译期与运行期分析及字符串常量池

【RS】哨兵系列数据下载(哨兵2号Sentinel-2波段介绍、下载) 以哨兵二号为示例,分享如何下载欧空局的哨兵系列数据 阅读详情

https://blog.youkuaiyun.com/zhuxinquan61/article/details/51952463


首先直接看这样的两个字符串的声明:
    String s1 = new String("TestString");

    String s2 = "TestString";
  • 1
  • 2
  • 3
对于这样两个字符串的声明在内存中的分布如下图:

这里写图片描述 
字符串s1由于是new的结果,那么首先s1作为一个变量会在栈内存中开辟空间用来保存该变量,然后在堆内存中开辟一块空间用来保存这个字符串对象,同时,也正是因为s1作为一个字符串,在开辟字符串对象空间的同时,在堆内存中也会把该字符串常量保存在字符串常量池当中,所以说,一次new的字符串对象会在堆内存当中产生两个字符串对象。 

对于字符串s2这种初始化赋值的方式,首先会在字符串常量池当中进行寻找,如果字符串常量池当中包含该字符串,则直接将该变量指向该字符串常量,如果不包含该字符串,则会新创建一个字符串常量到字符串常量池当中。

上述两种字符串创建的方式,s1会创建两个字符串对象,其中一个是new在堆内存上的字符串对象,一个是在字符串常量池中保存的一份字符串,而s2有可能不用创建对象,若该常量字符串存在则不需要再次进行创建,若不存在则需要在字符串常量池当中进行创建。

接下来看一下字符串在编译期和运行器的分析比较

同样先来一段代码:
public class StringObject {
    public static void main(String[] args) {
        //eg1
        String a = "a1";
        String a1 = "a" + 1;
        System.out.println(a == a1); //true

        //eg2
        String b = "b1";
        int bb = 1;
        String b1 = "b" + bb;
        System.out.println(b == b1); //false

        //eg3
        String c = "c1";
        final int cc = 1;
        String c1 = "c" + cc;
        System.out.println(c == c1); //true

        //eg4
        String d = "d1";
        final int dd = getDd();
        String d1 = "d" + dd;
        System.out.println(d == d1); //false
    }

    public static int getDd(){
        return 1;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
上述四种情况用来比较两个字符串对象是否为同一个对象
对于eg1中的a1和a,由于两个变量都是常量字符串,当变量a初始化后就会在字符串常量池当中含有”a1”字符串,创建a1时就会先从字符串常量池当中寻找,此时就会找到,直接将已有的字符串常量对象赋值给a1变量,因此a1和a的对象比较结果就相同。
对于eg2中的b1和b,由于bb是一个变量,因此只有在运行期才能确定,所以返回结果为false
对于eg3和eg2中的区别在与变量cc使用了final修饰符,也就是说此处的cc相当于一个常量,在编译期已经将其替换,所以就和eg1类似,两个字符串对象为为同一个对象
然而对于eg4,虽然变量dd前也使用了final进行修饰,但是变量dd的值本身是通过一个静态方法的返回值进行初始化的,方法的执行是在运行期,所以结果为两个对象不是同一个对象。

英飞凌TC3xx之一起认识GTM(八)如何使用DTM实现死区时间配置 本文简要介绍英飞凌TC3xx系列芯片的DTM模块结构,以及有哪些相关寄存器可用于实现相关配置。 阅读详情

相关推荐

基于单片机的自动喷淋系统设计【毕业设计】

随着人民生活质量提高与生活节奏的加快,城市居民对于花草绿植的家庭培养与装饰需求增加,随之因浇灌植物的需要,智能浇花系统的市场逐渐扩大。现有自动浇花系统大部分只能通过设置固定浇水时间而难以实现适时、适量浇水,或在植物环境土壤含水量低时进行报警而并不能实际补水。为克服局限性而设计以单片机为控制中心的自动浇花系统。通过湿度传感器检测目标植物环境土壤湿度数据,再经ADCO832将其放大转换为数字量,由单片机读取输出向LCD1602 显示屏显示并通过比对键盘向单片机所设置的湿度范围而利用中断服务程序进行补水需求判断。

qq_48771816的博客 1709

字符串编译期与运行期分析及字符串常量池

首先直接看这样的两个字符串的声明: String s1 = new String("TestString"); String s2 = "TestString";对于这样两个字符串的声明在内存中的分布如下图: 字符串s1由于是new的结果,那么首先s1作为一个变量会在栈内存中开辟空间用来保存该变量,然后在堆内存中开辟一块空间用来保存这个字符串对象,同时,也正是因为s1作为一个字符串,在

zhuxinquan的博客 1627

深入解析Android SoundTrigger架构:从HIDL到AIDL的演进与实践

本文深入解析Android SoundTrigger架构,从HIDL到AIDL的演进与实践。SoundTrigger是Android系统中低功耗语音唤醒的关键技术,通过分层设计和硬件协同实现高效语音识别。文章详细介绍了核心组件、HIDL与AIDL的对比及优化技巧,帮助开发者掌握语音模型优化和功耗管理。

brown的博客 230

boost::string_ref 编译期字符串的使用

std::string本身实现了对字符数组的管理工作,提供了string类常用的功能, 例如, 查找 大小写转换 构造 等等 但是std::string毕竟是运行期计算。众所周知,std C++11后,支持在编译器编译期间计算一部分常量值,这样可以减少运行期工作,提升程序性能。 这种编译期可以计算出的值叫做编译期常量值,在C++中的标识符为constexpr。 毕竟C++语言实现的初衷就是最大限度的提高性能。 运行期的性能已经提升得差不多了,就只能最大限度的压榨编译器的性能了。 毕竟编译程序是只做一次的

zhuge19870104的博客 549

TruckSim与Simulink联合仿真中的车轮转角精确控制策略

本文深入探讨了TruckSim与Simulink联合仿真中实现车轮转角精确控制的关键策略。针对多轴车辆路径跟踪时转角指令失灵的常见问题,核心在于正确配置TruckSim转向轴的外部输入模式(Advanced Settings),并确保仿真接口的稳定搭建。文章详细解析了从单轴到多轴协同转向的配置方法,并提供了提升MPC路径跟踪精度的实战技巧与调试经验。

weixin_29035147的博客 367

PyTorch深度学习实战(7)——批大小对神经网络训练的影响

在神经网络中,批( batch )是指一次输入网络进行训练或推断的一组样本。批处理( batch processing )是指将这一组样本同时输入网络进行计算的操作。本节中首先介绍批( Batch )的基本概念,并且介绍批大小在神经网络训练过程中的影响。

盼小辉丶的博客 1万+

C++利用常量表达式在编译期操作字符串

在打log的时候,往往有这样的需求,要把当前代码文件的文件名打印出来。 最简单的就是输出__FILE__宏。但是__FILE__实际上是包括文件名的完整路径,比如这样:/tmp/blablabla-XXXX-YYYY-ZZZZZZ/example.cpp这样的输出太过冗长,我们需要的实际上只是example.cpp这个时候要是老老实实地调函数把example.cpp切出来当然不难,但是

那些零零散散的算法 4082

【自适应滤波】自适应UKF,基于新息自适应调节Q和R,场景为雷达跟踪与滤波、MATLAB实现

本文提出了一种基于新息协方差匹配的自适应UKF(CM-AUKF)算法,用于解决噪声统计未知或时变场景下的目标跟踪问题。通过实时调整过程噪声协方差Q和观测噪声协方差R,CM-AUKF显著提升了跟踪精度和稳定性。仿真结果表明,相比传统UKF,CM-AUKF在位置和速度估计误差上分别降低了约50%和30%,且无需人工调参。该算法适用于无人机导航、雷达跟踪等动态环境,MATLAB代码可直接运行复现结果。自适应曲线显示算法能有效收敛到真实噪声参数,验证了其自适应能力。

985工科博士毕业,专攻定位、导航和滤波等算法研究。从业10年,主要使用MATLAB 329

编译期常量字符串拼接处理

随着C++ 11的语法越来越复杂,功能也越来越强。用泛型+返回类型推导的方法来实现常量字符串的处理,能实现宏实现不了的地方,并且在编译期实现 SO上的牛人太多了,以下是出处 http://stackoverflow.com/questions/15858141/conveniently-declaring-compile-time-strings-in-c/15890335#15890335 ...

weixin_34128839的博客 506

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南

在AI应用开发领域,工作流编排正成为连接大语言模型(LLM)能力与复杂业务逻辑的关键技术。其核心原理是将任务分解为模块化节点,通过可视化方式定义执行顺序与数据流向,从而实现灵活可控的自动化流程。这种范式极大地提升了开发效率,降低了技术门槛,使得开发者能够聚焦于业务设计而非底层代码。在技术价值层面,工作流编排支持检索增强生成(RAG)、多智能体协作等高级模式,并能通过人工干预节点确保关键流程的可靠性与合规性。其典型应用场景包括智能客服、自动化办公、数据分析助手等。本文以Flock平台为例,深入解析了如何利用其

weixin_26848497的博客 381

PHM2010刀具磨损预测完整实现

本文介绍了PHM2010刀具磨损预测项目的完整实现方案。项目采用PHM2010公开数据集,包含6个子数据集,记录了铣削加工过程中7个通道的传感器数据(切削力、振动和声发射信号)。技术路线包括数据预处理(截取中间10万点、小波降噪)、特征提取(时域9个、频域4个特征)、特征融合和皮尔逊相关系数筛选,最终使用BiLSTM模型进行训练和评估。环境配置基于Python 3.9,依赖NumPy、Pandas、PyTorch等库。数据加载和预处理阶段重点处理了传感器信号分段和磨损标签对齐问题,为后续建模奠定基础。

huanghm88的专栏 416

c语言编译时字符串长度,c ++ - 在编译时计算C字符串的长度。 这真的是一个constexpr吗?...

c ++ - 在编译时计算C字符串的长度。 这真的是一个constexpr吗?我正在尝试在编译时计算字符串文字的长度。 为此,我使用以下代码:#include int constexpr length(const char* str){return *str ? 1 + length(str + 1) : 0;}int main(){printf("%d %d", length("abcd"),...

weixin_35995377的博客 606

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

关于常量池,字符串常量池的整理

由于之前研究了一下JVM的内存划分,对里面方法区的常量池一知半解,于是想要探究一下 全局字符串池(string pool也有叫做string literal pool) 全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中(记住:string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在...

weixin_38719347的博客 5054

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

老版QQ原生表情gif动态

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

JAVA常量池

常量池分类 常量池大体可以分为:静态常量池,运行时常量池。 静态常量池: 存在于class文件中,比如经常使用的javap -verbose中,常量池总是在最前面把? 运行时常量池:就是在class文件被加载进了内存之后,常量池保存在了方法区中,通常说的常量池 值的是运行时常量池。所以呢,讨论的都是运行时常量池 字符串常量池 最最最流行的、最典型的就是字符串了 典型范例: Stri...

m0_37501154的博客 467

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

常量池、字符串常量池的整理

由于之前研究了一下JVM的内存划分,对里面方法区的常量池一知半解,于是想要探究一下 先看这篇 写得比较清晰 https://blog.youkuaiyun.com/tophawk/article/details/78704074(jdk1.8版本) https://blog.youkuaiyun.com/youyou1543724847/article/details/52337257 以下内容有点儿乱,还未整理...

MayMatrix 的博客 272

String常量池

一、第一步   当前所使用的jdk版本是1.8   首先我们需要注意的是有运行期与编译期,而运行期还得区分运行时的类加载过程与实际执行某个代码片段。   当代码为: String a=“abc” 时,由于字符串字面量会在编译期就被编译到.class二进制文件中,当虚拟机加载该class文件的时候,这种字符串字面量会被JVM初始化成一个String对象,存储在字符串常量池中,在jdk1.8里字符串常量池是在堆里的,而Constant Table\String table则在Native Memory,Con

gwokgwok137的博客 432

java String于常量池中的介绍

常量池 : 在编译期被确定,并被保存在已编译的.class文件中的一些数据: 它包括了关于类、方法、接口等中的常量,也包括字符串常量 ********************************************************************** 用new String()创建的字符串不是常量,不能在编译期就确定 所以new String()创建的字符串不放入...

beOkWithAnything 218

Java中String为什么可以不用new?

1. jvm为了提升性能和减少内存开销,避免字符的重复创建,其维护了一块特殊的内存空间,即字符串常量池,用来存储字符串常量。 2. 使用String直接赋值: String str=“abc”:可能创建一个或者不创建对象,如果”abc”在字符串池中不存在,会在java字符串池中创建一个String对象(”abc”),然后str指向这个内存地址,无论以后用这种方式创建多少个值为”abc”的字符串对象,始终只有一个内存地址被分配。 3.使用new String()赋值: String str=newStrin

琉璃的博客 3372

用javap命令反编译来分析字符串问题

编写Test.java。编译完后生成Test.class文件,然后对该文件运行javap -c Test命令,生成字节码指令。阅读并得出结论 一、s1和s2指向常量池的不同常量 ①java代码 public class Test {     public static void main(String[] args) throws IOException { ...

weixin_34306593的博客 140

String 类型字符串存储和拼接

链接:https://www.nowcoder.com/questionTerminal/f06ee75317c44b44b43b10b1ffc866bd 来源:牛客网  String str1="hello";     String str2="he"+"llo";   String str3="he"+new String("llo");  str1==str2 true

seulzz的博客 1787

美团面试题解析:用final 考验你对堆和栈的理解

* 微信公众号:码农搬砖 * 欢迎关注我们,获得更多的面试知识 */ public class TextFinal { ​ /** * 考题1 :请问 输出结果 */ public static void test1() { String s = "hello2"; final String s1 = "hello"; String s2 = s1 + 2; System.out.println(s =.

左耳的专栏 478

java常量池_JAVA常量池

java常量池是一个经久不衰的话题,也是面试官的最爱,题目花样百出。理论jvm虚拟内存分布:** 程序计数器是jvm执行程序的流水线,存放一些跳转指令,这个太高深,小菜不懂。** 本地方法栈是jvm调用操作系统方法所使用的栈。** 虚拟机栈是jvm执行java代码所使用的栈。** 方法区存放了一些常量、静态变量、类信息等,可以理解成class文件在内存中的存放位置。...

weixin_33167915的博客 144

深入理解字符串常量池

我们知道字符串的分配和其他对象分配一样,是需要消耗高昂的时间和空间的,而且字符串我们使用的非常多。JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池。 每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串...

yesr的博客 831

java8中的‘+‘的使用注意事项

当时以为s1和s6是相等的,没想到还有个编译期常量拼接和运行期变量拼接。1、编译期常量拼接(如 “a” + “b”、final 变量拼接):编译器会直接优化为拼接后的结果,存入字符串常量池。2、运行期变量拼接(如非 final 变量、对象引用):底层通过 StringBuilder(或 StringBuffer)的 append() 方法实现,最后调用 toString() 生成新字符串(存储在堆中)。

uaucome的博客 224

Java内存分配(三)

<br />String常量池问题的几个例子<br />  下面是几个常见例子的比较分析和理解:String a = "a1" ;   String b = "a"  + 1 ;    System.out.println((a == b)); //result = true   String a = "atrue" ;    String b = "a"  + "true" ;    System.out.println((a == b)); //result = true

liwen19840617的专栏 463

String和常量池的思考(随手一记)

随手记一下String和常量池的一些知识点。 首先需要大概的了解编译期和运行期两个概念。 当编写完JAVA程序之后,首先将java文件编译成class文件,这就是编译期要做的事情,在编译期编译器会对程序进行一些优化。 当class文件编译出来之后,开始运行程序,将class文件动态的加载进JVM,程序就进入了运行期。 常量池(以下名字不准确,是自己叫的): 静态常量池:程序编译完成之后,程序中一些不会改变的常量会保存到class文件中的一块地方,这里就是静态常量池 动态常量池:程序开始运行的时候,将静态常

NAPO687的博客 296
上一篇: request.getParameter()、request.getInputStream()和request.getReader()
下一篇: (重要)浅析Java中的final关键字 字符串常量
周末去看海
博客等级 码龄9年 50粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值