字符串如何像值类型一样行为,尽管它是引用类型
字符串像值类型一样表现,
引言
字符串是一种引用数据类型,用于存储文本。大多数开发者认为 string
是一种值类型,因为它表现得像值类型。 理解为什么 string
表现得像值类型,虽然它实际上是引用类型,这是一个小但非常重要的概念。 为了理解这一点,我们需要了解实际问题以及造成这种情况的原因。
在解释原因之前,我们需要理解值类型和引用类型。
值类型
一种将其内容存储在堆栈(内存中的一个特殊区域)中的数据类型。 值类型保存实际的值。 如果您将其赋值给另一个变量,该值将被直接复制,并且两个变量将独立工作。 让我们通过一个例子来理解。
Int a=50; //declare and initialize variable a.
Int b=50; //declare and initialize variable b.
b=a; //Assign variable a to b. Here only the value of variable will be copied to b.
//Now changes in variable a or b will not reflect to each other.
b=30; //Only value of b variable will change and variable a will hold 50 as its previous value.
引用类型
一种将其内容存储在堆(内存中的一个特殊区域)中的数据类型。 在引用类型变量中,它保存的是对象的引用(地址),而不是分配给该对象的值。 每当您将一个对象分配给另一个对象时,它将创建引用的第二个副本,该副本将指向同一位置。 因此,如果更改其中任何一个,都会反映到另一个,因为它们都指向同一位置。 让我们通过一个例子来理解。
Square sqr1 = new square (); //declaration of an object (reference type)
Square sqr2 = new square (); //declaration of another array (reference type)
sqr1.length = 10; //assign value to length property of square class (sqr1)
sqr2.length = 15; //assign value to length property of square class (sqr2)
sqr2= sqr1; //assign sqr1 to sqr2
sqr2.length=30; //Now in changing in sqr1 will reflect to sqr2.
在对值类型和引用类型有了基本了解之后,现在我们可以很容易地推断出 string
应该如何表现,因为它是一种引用类型,但我们看到的是,它表现得像一种值类型。 答案是因为 string
是不可变的。 这句话包含一些深度。 因此,有必要理解或更深入地了解可变和不可变的概念。
不可变
在不可变(意味着不可更改)对象中,对象的状态一旦创建就不能更改。 每次修改时,它不会在同一位置进行更改,而是在内存中创建一个新实例。
可变
在可变(意味着可更改)对象中,对象的状态可以在创建后更改。 任何更改都将更改内存中的同一位置。
在了解了值类型、引用类型以及可变和不可变之后,现在是时候找出为什么 string
作为引用类型却表现得像值类型的原因了。 原因是每当我们创建一个 string
并将该 string
的引用传递给另一个 string
时,它会复制被引用 string
的引用(内存地址),以便两个 string
都指向相同的位置。但是,当我们在任何一个 string
中进行更改时,它会在内存中创建一个新位置并在该位置更新文本。因此,另一个(第二个)string
将继续指向先前的位置。因此,在 string
进行任何更改后,两个变量将指向单独的内存位置。 让我们用一个例子来说明。
创建两个名为 str1
和 str2
的 string
。
string str1;
string str2;
两者将指向内存中的单独位置。
现在将 str1
赋值给 str2
。
str2=str1;
两个 string
都指向内存中的相同位置。 现在更改 str1
。 在这里,不可变的概念将适用(每次更改,都在内存中创建新位置)。
现在我们可以理解,str1
现在将位于新内存 (3) 中,而 str2
仍将位于先前内存位置 (1) 中,其中没有任何更改。 这就是为什么在任何修改时,string
不会被更新的原因。