一.字符串存储机制
公共语言运行时通过维护一个表来存放字符串,该表称为"暂存池",该容器的key是字符串内容,value是字符串在托管堆上的内存地址.
它包含程序中以编程方式声明或创建的每个唯一的字符串的一个引用。因此,具有特定值的字符串的实例在系统中只有一个。
例如,如果将同一字符串分配给几个变量,运行时就会从暂存池中检索对该字符串的相同引用,并将它分配给各个变量。
二.字符串创建解析
情况1.
String s1="hello"; //注意:这里s1赋值字符串常量
s1="world";//注意:这里s1赋值字符串常量
字符串横定性是指一个字符串一经创建,就不可改变。那么也就是说当我们改变s1值的时候,便会在托管堆上重新分配一块新的内存空间("world"),s1便指向这块新的内存空间,而不会影响到原有的内存地址上所存储的值。原有的内存空间("hello"),如果长时间没有其他String变量来指向它,很有可能会被回收或定期清理。
如图所示:
情况2.
string s1="hello"; //注意:这里s1赋值字符串常量
string s2="hello"; //注意:这里s2赋值字符串常量
s1把对象引用复制给了s2,s2指向s1的内存地址。可以说s1和s2是同一个对象,就像
User u2;
User u1=new User();
u2=u1;
如图所示:
情况4.
string s1="hello"; //注意:这里s1赋值字符串常量
string s2="world"; //注意:这里s2赋值字符串常量
s1和s2各分配新的内存空间,如下图所示:
三.字符串连接
string s1 ="a";和string s2 = "a" + "b";各进行了几次内存分配?
两段代码所分配内存的次数是一样的。在所有的字符串都是字符串常量时,编译器会在编译时将它们连接成一个字符串。也就是说在碰到诸如"a"+"b"这样的代码时,编译器会自动合并为"ab"
但如果是:string s1 = "hello";strings2 = "helloworld";string s3=s1+"world";就不一样了。注意//这里s3是字符串变量s1和常量"world"连接而成的。
测试1:
Console.WriteLine(Object.ReferenceEquals(s2,s3)) -------False
原因是s3是动态生成的字符串,这样的字符串是不会添加到暂存池中进行维护到的。具体存储在那里要进一步研究??
测试2:
Console.WriteLine(Object.ReferenceEquals(s2,s1)) -------False
s1 和 s2 是两个不同的对象(内存地址不同);
测试3:
s3 = String.Intern(s3);
Console.WriteLine(Object.ReferenceEquals(s2,s3)) -------True
Intern 方法使用暂存池来搜索与 s3 值相等的字符串。 如果存在这样的字符串,则返回暂存池中它的引用。 如果不存在,则向暂存池添加对 s3 的引用,然后返回该引用。
由于存在与s3 具有相同值的字符串s2, 将s2 引用赋给 s3。而 s2 和s3 内存引用是相等,因为它们引用同一字符串。
这篇文章是否让你对字符串有了更深刻的了解了呢,也许里面还有些不足之处,就算是抛砖引玉了吧,希望大家多多提问和发表意见,洗耳恭听。。。。。
分享到:
相关推荐
标题和描述均强调了在Java中处理`String`对象时可能遇到的陷阱,尤其是在理解和使用`String`的处理机制上。文章由天津工业大学软件工程专业的翁龙辉撰写,旨在深入剖析`String`在Java中的独特行为及其潜在的陷阱。...
它被广泛用于存储文本信息,而关于字符串创建的理解,以及"equals()"方法和"=="运算符的区别,是每个Java开发者都应深入掌握的知识点。 首先,让我们来探讨字符串的创建。在Java中,有多种创建字符串的方式: 1. *...
【字符串比较】在.NET开发中,字符串比较是一个常见的任务,`String.Compare()`方法是我们经常会用到的一个工具。...同时,理解`string`和`System.String`的差异,可以更好地进行跨语言交互和代码的可读性设计。
`String` 类内部使用一个字符数组 `char[] value` 来存储字符串的实际内容。一旦创建了一个 `String` 对象,它的内容就不能再被修改。这种设计保证了字符串对象的一致性和安全性,尤其是在多线程环境中。例如,在...
首先,自定义String类的主要目的是模拟Java内置的String类的工作机制。通常,这样的类会包含以下关键元素: 1. **字符数组**:一个字符串是由字符组成的,因此,自定义的String类通常会有一个私有的字符数组来存储...
本测试程序旨在深入理解和探索`String`类的一些核心功能和内部机制。以下是一些关于`String`类的关键知识点: 1. **不可变性**:`String`对象在创建后就不能更改。这意味着一旦创建了`String`实例,它的值就固定了...
根据提供的文件信息,本文将围绕“String容量大小区分”这一主题进行深入探讨,结合Java语言中的String类特性,解析字符串在不同场景下的容量变化及内存管理机制。 ### 标题和描述解读:“String容量大小区分” 该...
本篇文章将详细解释Java中的String池概念及其重要性,并通过一个示例代码深入理解String池的工作机制。 #### String池的基本概念 Java中的String池是一个特殊的数据结构,它存储了所有被程序引用的字符串字面量...
《深入理解JVM实战篇-String类》 在Java编程中,String类是使用最频繁的类之一,它涉及到许多底层机制,特别是与JVM(Java虚拟机)的交互。本文将探讨String类的一些关键特性,包括字面量与运行时常量池、String的...
这种方式创建的`String`对象会存储在常量池中,因为它们是编译时常量。 2. **构造函数创建**: `String`类提供了多个构造函数,允许我们通过字符数组或另一个`String`对象来创建新对象。例如: ```java char[] ...
《深入理解JVM中的StringTable》 在Java虚拟机(JVM)中,StringTable扮演着至关重要的角色,它是字符串常量池的实现,存放着程序中所有的字符串...通过深入理解这一机制,我们可以更好地编写出高效、内存友好的代码。
### String类创建对象问题 ...总结来说,了解 `String` 类的创建过程及其在内存中的存储方式对于理解 Java 中字符串的工作机制至关重要。正确地使用字符串不仅可以提升程序的性能,还能避免潜在的内存泄漏等问题。
Java中的String类是一个重要的数据类型,用于存储和操作字符串数据。String类的特点是不可变性,也就是说,一旦String对象被创建,其值就无法改变。这一特性对于Java内存管理有着重要影响,因为String对象会存储在...
4. **错误处理**:为了增加程序的健壮性,自定义的字符串函数可能包含了错误处理机制,如检查输入参数的有效性,处理内存分配失败等。 5. **效率优化**:由于C语言标准库中的某些字符串函数可能会有性能上的瓶颈,...
### Java String对象的经典问题 #### 一、String 类与对象机制概述 在Java中,`String`类是一个非常重要的类,它提供...通过以上分析可以看出,深入理解`String`类和对象机制对于编写高效、可靠的Java程序至关重要。
#### 二、String与byte[]的转换机制 在Java中,可以通过以下几种方式实现`String`与`byte[]`之间的转换: 1. **String转byte[]**: - `getBytes()`: `String`类提供了一个`getBytes()`方法来将字符串转换为字节...
Java中的String是一个非常重要的类,它提供了两种创建方式和一种特殊的存储机制(String intern pool),并且String类中声明了一个char[]数组和一个int类型的变量hash,用于存储字符串的内容和哈希值。
在.NET框架中,`List<T>` 和 `string[]` 是两种常用的数据结构,它们都用于存储字符串类型的集合。然而,在具体使用时,这两种数据结构之间存在一些重要的差异。本文将详细介绍 `List<string>` 与 `string[]` 的区别...
- **优化字符串复制**:对于频繁复制的场景,可以考虑引入“写时复制”(Copy-On-Write, COW)机制来提高效率。 - **预分配空间**:对于预期会增长的字符串,可以在构造函数中预分配一定的额外空间,以减少后续重新...