图解String类型的不可变性及其原因

1.String的不可变性

String s=“abcd”;

上面的语句定义了一个字符串变量s。该变量指向字符串“abcd”,当初始化变量s时,会在堆中为s非配内容空间。例如以下图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXVuemVy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

当将字符串变量,赋值给还有一个字符串变量时,比如:String s2=s。

此时。s2和s是同样的字符串对象。例如以下图所看到的:

当一个字符串连接其它字符时。他就指向了新的字符串对象,比如。s=s.concat("ef“)。 例如以下图所看到的

当一个字符串在堆中被分配内容时,它就是不可变的,不论什么String的方法都无法改变字符串本身,但它能够返回一个新的字符串对象。

假设须要能够改动的字符串对象,能够使用StringBuffer和StringBuilder,StringBuffer是线程安全的,因为StringBuilder不须要进行同步操作,StringBuilder是比較高速的。

2.String 不可变性的原因

1)字符串池(String pool)的需求

在Java中,当初始化一个字符串变量时。假设字符串已经存在。就不会创建一个新的字符串变量,而是返回存在字符串的引用。

比如: String string1="abcd";

String string2="abcd";

这两行代码在堆中仅仅会创建一个字符串对象。

假设字符串是可变的。改变还有一个字符串变量。就会使还有一个字符串变量指向错误的值。

2)缓存字符串hashcode码的须要

字符串的hashcode是常常被使用的。字符串的不变性确保了hashcode的值一直是一样的,在须要hashcode时,就不须要每次都计算,这样会非常高效。

3)出于安全性考虑

字符串常常作为网络连接、数据库连接等參数。不可变就能够保证连接的安全性。

时间: 2024-10-03 23:00:40

图解String类型的不可变性及其原因的相关文章

C#中string类型的不可变性

string是C#中比较常用的字符串类型,之前一直都只是使用它,却没有深入的去了解,今天在书中忽然看到它具有不可变性:于是便仔细了解了一下. //声明并初始化string类型变量 string Text = “Hello”; //对string类型变量赋值 Text = “Hi” 在这里,在把Hi字符串赋给string变量Text之前 内存首先会重新初始化一块区域,并把区域的值初始化为Hi.之后,这块内存的地址将赋给变量Text,而原来存放hello的内存区域则不会改变,可以看出,string类

Java中String类型的不可变性和驻留池

一 基本概念 可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当获得这个类的一个实例引用时,可以改变这个实例的内容. 不可变类:不可变类的实例一但创建,其内在成员变量的值就不能被修改.其中String类就是不可变类的经典应用. 二 例子 package cn.xy.test; public class StringTest{ /**  * a的值在编译时就被确定下来,故其值"xy"被放入String的驻留池(驻留池在堆中)并被a指向.

java中特殊的String类型

Java中String是一个特殊的包装类数据有两种创建形式: String s = "abc"; String s = new String("abc"); 第一种先在栈中创建一个对String类的对象引用变量s,然后去查找"abc"是否被保存在字符串常量池中,如果没有则在栈中创建三个char型的值 'a'.'b'.'c',然后在堆中创建一个String对象object,它的值是刚才在栈中创建的三个char型值组成的数组{'a'.'b'. 'c'

C# string类型遇到的两个问题

最近在维护一位离职的同事写的WPF代码,偶然发现他使用C# string类型的两个问题,在这里记录一下. 1. 使用Trim函数移除字串中的空格.换行符等字符串. csRet.Trim(new char[] { '\r', '\n', '\t', ' ' });if (!csRet.Equals(string.Empty)) statement1; else statement2; 上述代码的意图为:移除string类型变量csRet开头和结尾处的换行符.制表符.空格符之后,判断该字符串是否是空

使用==比较String类型

String类型的比 public class StringDemo { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); System.out.println(s1 == s2);//true System.out.println(s1 == s3);//false } } 按

Java中String类型的参数传递问题的解析

一.引入示例 public class StringAsParamOfMethodDemo { public static void main(String[] args) { StringAsParamOfMethodDemo sapm = new StringAsParamOfMethodDemo(); sapm.testA(); } private void testA() { String originalStr = "original"; System.out.println

C#string类型总结

个人笔记分享,知识点以及小练习 字符串的特性:不可变性,每对字符串做拼接或者重新赋值之类的操作,都会在内存中产生一个新的实例. 所以说,在.Net平台下,如果你对一个字符串进行大量的拼接赋值等操作,会产生大量的垃圾. ---->我们可以将字符串看做是char类型的只读数组. --->当我们以索引的方式去访问某一个字符串的时候,获得是char类型 空和null有什么区别,空在内存上开空间了,null没有 字符串的常用函数 1.ToCharArray():将一个字符串转换成一个char类型的数组.

图解值类型

一名正在学习.net的学生 写这篇文章的主要原因是: 值类型或引用类型大多人可能只了解表层的含义, 而忽略的它们核心的原理. 希望大家看完以后,对值类型和引用类型会有更深的收获 文章是我平时在课室写的,由于没有网络,是在word写,然后转成pdf,再转成jpg. 也许有些内容可能表达不是很专业,或者有错误,希望各位指正 图解值类型,布布扣,bubuko.com

java内存分配和String类型的深度解析(转)

一.引题 在java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合java内存分配深度分析 关于String的许多令人迷惑的问题.下面是本文将要涉及到的一些问题,如果读者对这些问题都了如指掌,则可忽略此文. 1.java内存具体指哪块内存?这块内存区域为什么要进行划分?是如何划分的?划分之后每块区域的作用是什么?如何设置各个区域的大小? 2.String类型在执行连接操作时,效率为什么会比StringBuffer或者StringBu