string机制1

如何在 R 中使用 Gamma 分布(附示例) 在统计学中,伽马分布通常用于模拟与等待时间相关的概率。我们可以使用以下函数来处理 R 中的 gamma 分布:dgamma(x, shape, rate) – 找到具有特定形状和速率参数的 gamma 分布的密度函数值。 pgamma(q, shape, rate) – 找到具有特定形状和速率参数的伽马分布的累积密度函数值。 qgamma(p, shape, rate) – 找到具有特定形状和速率参数的 gamma 分布的逆累积密度函数值。 rgamma(n, shape, rate) – 生成 n 个随机 阅读详情

1.String类概念

(1)String是final的,不可被继承。public final class String。String是的本质是字符数组char[], 并且其值不可改变。private final char value[];

(2)Java运行时会维护一个String Pool(String池)。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,仅仅存在于方法的堆栈区。

(3)创建字符串的方式很多,归纳起来有三类:(1)使用new关键字创建字符串-->String s1 = new String("abc");(2)直接指定-->String s2 = "abc";(3)用串联生成新的字符串-->String s3 = "ab" + "c";

2.String对象创建的机制

原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个s在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。例如:String str="abc";这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,它的判断依据是String 类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。

原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。而不在常量池中创建String对象,只有使用了str.intern(),才会在常量池中创建一个String对象。

原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

最后,有几点问题请大家注意:String a; 与String a=null在作为类变量时候是等价的,在局部变量则不同。null表示一个空引用,String a=null意思是在栈中声明了a,但是这个a没有指向任何地址。此时我们注意到String a在栈中声明了a,但是也没有指向任何地址,但是java的语法检查如果在局部变量中,String a是不能直接使用的,String a=null中的这个a可以直接使用。

3.经典面试题

(1)String s = new String("abc");创建了几个String Object? 答:[两个,pool中1个,heap中1个]

(2)String s0 = new String("abc");String s1 = new String("abc");创建了几个String Object?答:[三个,pool中1个,heap中2个]

(3)解释

涉及概念:字符串池[pool of literal strings]的字符串对象和堆[heap]中的字符串对象。

字符串对象的创建:由于字符串对象的大量使用[它是一个对象,一般而言普通对象总是在heap分配内存],Java中为了节省内存空间和运行时间,在编译阶段就把所有的字符串文字放到一个字符串池[pool of literal strings]中,而运行时字符串池成为常量池的一部分。字符串池的好处,就是该池中所有相同的字符串常量被合并,只占用一个空间。另一种解释:在JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,因此它提高了效率。由于String类是final的,它的值一经创建就不可改变,因此我们不用担心String对象共享而带来程序的混乱。字符串池由String类维护,我们可以调用intern()方法来访问字符串池。

现在看String s = new String("abc")语句,在执行new String()时,先检查pool中有没有"abc"对象,如果没有,则先在pool中创建一个"abc"对象,再将其复制一份放到heap中,并且把heap中的这个对象的引用交给s持有,这条语句就创建了2个String对象;如果有则将pool中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s持有,这条语句就创建了1个String对象(也可以理解为:如果有则新创建的"abc"对象将原有pool中的"abc"对象覆盖,这样可以勉强说创建了2个String对象)。

补充:常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。jdk编译时会将字符串池并入常量池。

4.举例

  1. public static void main(String[] args) {
  2.     String str_0 = "forrest";
  3.     String str_1 = "forrest";
  4.     if (str_0 == str_1) System.out.println("pool中值创建了一个String对象:/"forrest/", str_0和str_1分别对其进行了引用");
  5.     else System.out.println("Trouble");
  6.     
  7.     String str_2 = "vivian";
  8.     String str_3 = new String("vivian");
  9.     String str_4 = new String("vivian");
  10.     if (str_2 != str_3) System.out.println("str_2是对pool中String对象引用, str_3是对heap中String对象引用, 所以二者不是引用的同一个对象");
  11.     else System.out.println("Trouble");
  12.     if (str_2 != str_4) System.out.println("str_2是对pool中String对象引用, str_4是对heap中String对象引用, 所以二者不是引用的同一个对象");
  13.     else System.out.println("Trouble");
  14.     if (str_3 != str_4) System.out.println("str_3和str_4都是对heap中String对象引用, 但二者引用对象的内存地址不同, 所以二者不是引用的同一个对象");
  15.     else System.out.println("Trouble");
  16.     
  17.     String str_5 = str_3.intern(); //把str_3在heap中的String对象复制到loop中(虽然在String str_3 = new String("vivian")时已经在loop中创建了一份, 但intern()方法会要求重新复制),并将loop中这个对象引用到str_5
  18.     if (str_5 != str_3) System.out.println("str_5是对pool中String对象引用, str_3是对heap中String对象引用, 所以二者不是引用的同一个对象");
  19.     else System.out.println("Trouble");
  20.     if (str_5 == str_2) System.out.println("str_5和str_2都是对loop中某一String对象引用, 所以二者引用的是同一个对象");
  21.     else System.out.println("Trouble");
  22.     
  23.     str_4.intern();
  24.     if (str_4 != str_2) System.out.println("str_4虽然执行了str_4.intern(), 但它的返回值没有赋给str_4, 所以str_4和str_2不是引用的同一个对象");
  25.     else System.out.println("Trouble");
  26.     if (str_4.intern() == str_2) System.out.println("str_4.intern()和str_2都是对loop中某一String对象引用, 所以二者引用的是同一个对象");
  27.     else System.out.println("Trouble");
  28.     if (str_4.intern() != str_4) System.out.println("str_4.intern()是对pool中String对象引用, str_4是对heap中String对象引用, 所以二者不是引用的同一个对象");
  29.     else System.out.println("Trouble");
  30. }
  31. /*
  32.  * 输出为:
  33.  * pool中值创建了一个String对象:"forrest", str_0和str_1分别对其进行了引用
  34.  * str_2是对pool中String对象引用, str_3是对heap中String对象引用, 所以二者不是引用的同一个对象
  35.  * str_2是对pool中String对象引用, str_4是对heap中String对象引用, 所以二者不是引用的同一个对象
  36.  * str_3和str_4都是对heap中String对象引用, 但二者引用对象的内存地址不同, 所以二者不是引用的同一个对象
  37.  * str_5是对pool中String对象引用, str_3是对heap中String对象引用, 所以二者不是引用的同一个对象
  38.  * str_5和str_2都是对loop中某一String对象引用, 所以二者引用的是同一个对象
  39.  * str_4虽然执行了str_4.intern(), 但它的返回值没有赋给str_4, 所以str_4和str_2不是引用的同一个对象
  40.  * str_4.intern()和str_2都是对loop中某一String对象引用, 所以二者引用的是同一个对象
  41.  * str_4.intern()是对pool中String对象引用, str_4是对heap中String对象引用, 所以二者不是引用的同一个对象
  42.  * 
  43.  * */
  1. public static void main(String[] args) {
  2.     String a = "ab";
  3.     String b = "cd";
  4.     String c = "abcd";
  5.     String d = "ab" + "cd"; 
  6.     
  7.     // 如果d和c指向了同一个对象,则说明d被加入字符串池 
  8.     if (c == d) System.out.println("/"ab/"+/"cd/" 创建的对象 /"加入了/" 字符串池中"); 
  9.     else System.out.println("/"ab/"+/"cd/" 创建的对象 /"没加入/" 字符串池中"); 
  10.     String e = a + "cd"; 
  11.     // 如果e和c指向了同一个对象,则说明e也被加入了字符串池 
  12.     if (e == c) System.out.println("a +/"cd/" 创建的对象 /"加入了/" 字符串池中"); 
  13.     else System.out.println("a +/"cd/" 创建的对象 /"没加入/" 字符串池中"); 
  14.     String f = "ab" + b; 
  15.     // 如果f和c指向了同一个对象,则说明f也被加入了字符串池 
  16.     if (f == c) System.out.println("/"ab/"+ b 创建的对象 /"加入了/" 字符串池中");  
  17.     else System.out.println("/"ab/"+ b 创建的对象 /"没加入/" 字符串池中"); 
  18.     String g = a + b; 
  19.     // 如果g和c指向了同一个对象,则说明g也被加入了字符串池 
  20.     if (g == c) System.out.println("a + b 创建的对象 /"加入了/" 字符串池中"); 
  21.     else System.out.println("a + b 创建的对象 /"没加入/" 字符串池中"); 
  22. }
  23. /*
  24.  * 输出为:
  25.  * "ab"+"cd" 创建的对象 "加入了" 字符串池中
  26.  * a +"cd" 创建的对象 "没加入" 字符串池中
  27.  * "ab"+ b 创建的对象 "没加入" 字符串池中
  28.  * a + b 创建的对象 "没加入" 字符串池中
  29.  * 
  30.  * */

从第二段代码结果中我们不难看出,只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中;对于类似str=1+"AAA"+2+3这种强制类型转化形成的String对象也不会放到pool中的。对此我们不再赘述。因此我们提倡大家用引号包含文本的方式来创建String对象以提高效率,实际上这也是我们在编程中常采用的。

Coze智能体实战:接口需求分析和接口调试 AI智能体的需求:能根据接口文档提取接口信息以及设计接口测试点,并进行接口调试返回接口测试结果。 阅读详情

相关推荐

Truncated SVD for faster dection

Truncated SVD方法最先被提出在《Fast R-CNN》论文中,用于降低全连接层的运算量,提升模型的速度。在卷积神经网络的分类任务中,FC层的运算速度远远大于CONV层,而在Fast R-CNN的目标检测任务中,大多数的运算时间发生在FC 的运算中,是因为针对每张输入图片,只进行一次卷积操作,而要对生成的Region Proposal,大致两千个,进行全连接操作进行分类与Bounding...

weixin_35747666的博客 1535

string机制

1.String类概念 (1)String是final的,不可被继承。public final class String。String是的本质是字符数组char[], 并且其值不可改变。private final char value[]; (2)Java运行时会维护一个String Pool(String池)。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重

kite30的博客 624

MATLAB机械臂轨迹规划:在关节空间中生成多项式轨迹以及 jtraj函数(内容超详细讲解)

matlab机器人仿真,关节空间多项式轨迹生成

qq_40969179的博客 1万+

Java中String对象创建机制详解(面试必问)

Java String面试相关问题详解,四种String对象创建机制,String本质,String与StringBuffer异同,常量池,Java内存模型;

Leeon的博客 4947

训练AI:从数据收集到模型部署的完整指南

如果你刚开始接触AI,建议先学习一些基础的编程和机器学习知识,还可以使用现成的AI平台和工具来帮助你训练AI模型。在这篇文章中,我们将详细探讨从数据收集到模型部署的完整步骤,并提供一些有用的技巧和工具,以帮助你成功地训练自己的AI模型。在收集数据时,你需要从可靠的数据源(如数据仓库、数据集市、API接口)获取数据,确保数据的准确性和完整性。常用的划分比例是70%的数据集用于训练模型、15%的数据集用于验证模型,5%的数据集用于超参数调整,最后10%的数据集用于测试模型的性能。测试数据集用于测试模型的性能。

a_wsnd的博客 4166

11、RK3566/3568 Android11切割屏幕 长条屏 显示

在使用 RK3566 平台进行 Android 11 开发时,遇到切割屏(长条屏)显示画面不全。本文将详细介绍如何配置,以及如何修改 HWComposer 来调整显示区域,解决图像缩放问题。我这边屏幕是lvds接口的,分辨率1920 1080实际的屏物理尺寸是1920x463。

qq_39451352的博客 252

关于string的内存机制

5. 关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤: (1)先定义一个名为str的对String类的对象引用变量:String str; (2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o 的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对

andyzhaojianhui的专栏 421

工商银行软件开发中心数据安全监测溯源防护体系建设成果及展望

结合业界先进溯源理念和我行管理要求,依托大数据、分布式搜索分析引擎等技术,构建PB级海量数据加工分析和小时级快速核验、检索、溯源手段(如图6所示),支撑6种客户敏感信息关键要素的单一或组合溯源,形成行之有效的数据安全溯源流程,配套落地自动化快速泄露样本真实性核验和灵活高效的溯源能力,通过数据相关属性的自动化分析,实现追踪泄露源头、明确泄露路径的目标,为有效应对数据安全事件,降低和消除风险与不良影响,开展事后追责处置工作提供体系化解决方案。提高数据排查的自动化程度和排查效率,降低人工成本。

银行信息系统应用架构详解 222

String 内存机制管理

JVM运行的时候,将内存分为两个部分,一部分

Alisa11的专栏 2561

在jetson上对fastdeploy进行源码编译(完整版)

在大多数Linux发行版中,你可以使用包管理器安装Python开发包。根据jetpack的版本选择对应的推理库版本。在~/.bashrc中写入这三行。

如果想成为中心,那么就到中心去吧。 678

【AI Agent系列】【MetaGPT】9. 一句话订阅专属信息 - 订阅智能体进阶,实现一个更通用的订阅智能体(2)

订阅智能体进阶(2)。不用爬虫,直接提取网页信息。从RunSubscription分离出AddSubscriptionTask的action,并且让SubscriptionRunner单独运行。

同学小张的博客 1587

String与new String的区别

String与new String的区别 转载▼ // ==与equals的区别: // ==: // 1、比较的是操作符两端的操作数是否是同一个对象 // 2、两边的操作数必须是同一类型的(可以是父子类之间)才能编译通过。 // 3、比较的是地址,如果是具体的阿拉伯数字的比较,值相等则为TRUE,如: // int a=10 与 long b=10L 与 dou

breeze666的专栏 669

【Unity】 预制体Prefab使用说明

在 Unity 中,Prefab 是一个可以预先制作并重复使用的 GameObject 或组件集合,Prefab 中的 GameObject 可以有子对象和其他组件。

灵境引路人 2849

C++ STL 完整入门笔记[1]:string 核心底层机制与高频算法实战

是 C++ 最常用的字符串容器,很多开发者只会简单调用push_backsubstr,却不了解其容量扩容、迭代器分类、内存伸缩、性能优化底层逻辑;同时字符串大数运算也是面试高频算法题。本文结合图示拆解 string 底层特性,并对比两种大数相加写法的性能差距。迭代器:只读场景优先,逆序遍历用;容量优化:已知字符串最大长度必须调用reserve,杜绝频繁扩容;增删性能:避免begin()位置inserterase,优先尾部操作,需要逆序结果先尾插再reverse;内存伸缩。

dajuc的博客 645

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

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

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【源码 JDK 1.8】String的源码解读

【代码】【源码 JDK 1.8】String的源码解读。

Number_In的博客 549

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

String与StringTable串池机制,string.concat()与intern()方法底层,intern()方法jdk1.6,1.8区别

String字符串 concat方法拼接 String x="a"; String y="b"; x.concat(y) concat源码中容易得出,concat方法通过创建一个长度为两字符串长度之和的byte数组来存放两字符串,然后将两个字符串依次放入数组中,实现了字符串的拼接。 至于为什么使用byte数组,上面讲过,String类型底层使用byte数组存储char数组,因此concat使用byte数组来存储字符串,如果用其他类型的数组就要进行类型转换。 注意:concat方法并不会对原对象进行

weixin_47071411的博客 765

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

基于JDK1.6和JDK1.7对String.intern()方法的理解

最近看了深入理解Java虚拟机,对String.intern()方法虚拟机的实现很是不理解,经过查找网上的各类文章,现在总结一部分。 在理解String.intern()方法之前,我觉得首先应该了解一下通过创建对象的方式和直接创建字符串的方式对象生成机制便于理解一下代码。 String str1 = new String("1");//--创建对象的方式 这种创建方式,是在堆中创建一个字符串...

qq_35850405的博客 323

String 的去重操作

一点睛 注意这里说的重复,指的是在堆中的数据,而不是常量池中的,因为常量池中的本身就不会重复。 背景:对许多 Java 应用(有大的也有小的)做的测试得出以下结果: 堆存活数据集合里面 String 对象占了 25% 堆存活数据集合里面重复的String对象有 13.5% String 对象的平均长度是 45 许多大规模的 Java 应用的瓶颈在于内存,测试表明,在这些类型的应用里面,Java 堆中存活的数据集合差不多 25% 是 String 对象。更进一步,这里面差..

实践求真知 3642

jdk 1.8 String

1)String变量到底存储在哪里?(JDK8) JDK1.8版本中,String常量池已经从方法区中的运行时常量池分离到堆中了,那么在堆中的String常量池里 存的是String对象还是引用呢?答案是对象。 例子1: String s1 = "abc"; String s2 = "abc"; System.out.println(s1==s2); // trueJVM首先会去字符串池中查找...

明天的你会感谢今天的自己 1108

Java String 底层实现 从 char [] 到 Compact String 内存优化

Java 并发编程中的活锁(Livelock)与饥饿(Starvation)问题

zqdaUkA35的博客 404

jdk1.6和1.7 String常量池

在jdk1.6中,该方法把字符串的值复制到常量区,然后返回常量区里这个字符串的值; 在jdk1.7~里,该方法在常量区记录该字符串首次出现的实例引用,然后返回该地址,常量区可以保存字面量也可以保存字符串对象在堆中的引用。 /** * 这里都是基于1.7~ 想了解intern()就需要了解 栈 堆 运行时常量池。了解一个字符串对象到底是怎样存储的!才能灵活运用 * intern()作用分析 * 判断这个常量是否存在于常量池。 * 1.存在:判断存在内容是引用还是常量。如果是引用,返回引用地址指向堆空间对象。如

qq_36826255的博客 285

String 详解

本文给大家介绍了 String 创建对象的方式,通过例子分别介绍这些方式的区别;另外还介绍了在不同版本下的常量池的实现机制,博文可能会存在错误的地方,望指出,一起交流交流。

leewccc的博客 1402

String的面试知识点

String的变化历程 在java6之前,String对象主要有四个成员变量:char[]数组,offset偏移量,count字符数量,hash哈希值;通过offset和count两个属性可以定位char[]数组,共享数组对象,但是有可能会导致内存泄露。占用空间不被释放,比如源字符串很大,subString()一个字符,然后i只调用分割后的,那麽就会会共享原String对象,不会被GC,造成内存泄露。 泄露:调用String对象的substring方法后指向的对象地址并没有发生改变,只是改变的是偏移量,这样

code_mzh的博客 301

JDK1.8版本java字符串常量池里存的是String对象还是引用?

原创地址高楼大厦,都是平地起的。整个java体系,其实就一本秘籍,那就是java基础!就我本人这么多年JAVA研发方面的工作经验来看,基础如果打的扎实,在实际开发工作中会带来极大的助益。最近有个机会整理JAVA基础相关知识,整理到JVM内存模型这部分的时候,画了两张图,记载在此,供感兴趣的新手参考。第一张:JDK1.8 - JVM内存模型说明程序计数器:它的生命周期与线程相同,线程私有。较小的内存...

shy244的博客 1992

String的内存地址比较以及使用javap对其分析【基于JDK1.8】

String的内存地址比较以及使用javap对其分析【基于JDK1.8】 首先来看下面一段代码,思考输出? public static void main(String[] args) { String strBase = "Rover"; String str0 = "Rover001"; String str1 = "Rover" + &qu

ccv5873的博客 335

String s = new String("xyz");创建了几个字符串对象?

两个对象,要理解这个,就要知道string类的工作原理。下面来慢慢分析一下: public class StringTest { public static void main(String[] args){ String s1="Hello"; String s2="Hello"; String s3=new String("Hel...

一个傻子程序媛的博客 1万+
上一篇: String、StringBuffer和StringBuilder
下一篇: string机制2
ForWayfarer
博客等级 码龄20年 60粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值