Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “我们说”的确切含义是什么;整数是不可变的;_Java_C++ - Fatal编程技术网

Java “我们说”的确切含义是什么;整数是不可变的;

Java “我们说”的确切含义是什么;整数是不可变的;,java,c++,Java,C++,我对“不变”的概念感到困惑。我们的教授每天都在说“整数是不可变的!字符串是不可变的”,这到底是什么意思 更一般的问题是,我们如何知道数据结构是否是不变的 感谢如果对象的状态在构造后无法更改,则认为该对象是不可变的 来源:如果对象在构造后状态无法更改,则认为该对象是不可变的 来源:不可变的内容高度依赖于语言,但不可变对象只是一个在创建后无法更改的对象 这通常意味着: int x = 4; x = 5;//not 'allowed' 这在原语(如int)可以是不可变的语言(如Scala等函数式语言

我对“不变”的概念感到困惑。我们的教授每天都在说“整数是不可变的!字符串是不可变的”,这到底是什么意思

更一般的问题是,我们如何知道数据结构是否是不变的


感谢

如果对象的状态在构造后无法更改,则认为该对象是不可变的


来源:

如果对象在构造后状态无法更改,则认为该对象是不可变的


来源:

不可变的内容高度依赖于语言,但不可变对象只是一个在创建后无法更改的对象

这通常意味着:

int x = 4;
x = 5;//not 'allowed'
这在原语(如int)可以是不可变的语言(如Scala等函数式语言)中可以看到

OOP中的大多数对象实际上是指向内存中某个位置的指针。如果该对象是不可变的,则内存中的该位置不能更改其内容。对于Java中的
字符串
,我们看到了这种情况:

String a = "Hello"; //points to some memory location, lets say '0x00001'
a = a + " World!"; //points to a new locations, lets say '0x00002'
System.out.println(a);//prints the contents of memory location '0x00002'
在本例中,
a
实际上指向内存中第2行之后的一个完全不同的位置。这意味着,另一个具有不同作用域的线程已经传递了
a
将不会看到“Hello World!”,而是看到“Hello”:

无论调用顺序如何,这两个线程都将输出以下内容:

"Hello Hello!" //thread 1
"Hello World!" //thread 2

不可变的东西高度依赖于语言,但不可变对象只是一个在创建后无法更改的对象

这通常意味着:

int x = 4;
x = 5;//not 'allowed'
这在原语(如int)可以是不可变的语言(如Scala等函数式语言)中可以看到

OOP中的大多数对象实际上是指向内存中某个位置的指针。如果该对象是不可变的,则内存中的该位置不能更改其内容。对于Java中的
字符串
,我们看到了这种情况:

String a = "Hello"; //points to some memory location, lets say '0x00001'
a = a + " World!"; //points to a new locations, lets say '0x00002'
System.out.println(a);//prints the contents of memory location '0x00002'
在本例中,
a
实际上指向内存中第2行之后的一个完全不同的位置。这意味着,另一个具有不同作用域的线程已经传递了
a
将不会看到“Hello World!”,而是看到“Hello”:

无论调用顺序如何,这两个线程都将输出以下内容:

"Hello Hello!" //thread 1
"Hello World!" //thread 2

通常,这意味着您不能对将更改

有时人们将值类型称为不可变的

//theres no way for this to be mutable but this is an example of a value type
int a = 5
int b = a;
b=9
与以下类类型不同,a不会更改

MyClass a = new MyClass
MyClass b = a
b.DoSomething()
//a is now changed

通常,这意味着您不能对将更改

有时人们将值类型称为不可变的

//theres no way for this to be mutable but this is an example of a value type
int a = 5
int b = a;
b=9
与以下类类型不同,a不会更改

MyClass a = new MyClass
MyClass b = a
b.DoSomething()
//a is now changed

不可变对象是指一旦实例化就无法修改的对象。如果必须修改,将创建一个新对象并指向引用


INT不是不可变的。

不可变对象是指一旦实例化就无法修改的对象。如果必须修改,将创建一个新对象并指向引用

int不是不可变的。

不可变性(对象或值,而不是变量)通常意味着无法对值进行就地更改。(会传播到其他引用的引用)这意味着如果您有以下内容:

String a = "foo";
您无法对
a
执行任何更改其值的操作。也就是说,您不能有一个会导致以下行为的假设方法
append()

String a = "foo";
a.append("bar"); // a is not reassigned
System.out.println(a); // prints "foobar"
您可以将其与集合等可变对象进行对比:

int[] as = new String[] { "foo" };
as[0] = "bar"; // we're changing `as` in-place - not the Strings stored in it
System.out.println(as[0]); // prints "bar"
对于Java来说,基本类型并不是一个很好的示例选择,因为您不能有对它们的多个引用,也无法证明变异和重新分配之间的区别。

不变性(对象或值,而不是变量)通常意味着无法对值进行就地更改。(会传播到其他引用的引用)这意味着如果您有以下内容:

String a = "foo";
您无法对
a
执行任何更改其值的操作。也就是说,您不能有一个会导致以下行为的假设方法
append()

String a = "foo";
a.append("bar"); // a is not reassigned
System.out.println(a); // prints "foobar"
您可以将其与集合等可变对象进行对比:

int[] as = new String[] { "foo" };
as[0] = "bar"; // we're changing `as` in-place - not the Strings stored in it
System.out.println(as[0]); // prints "bar"

对于Java来说,基元类型并不是一个很好的示例选择,因为不能有多个对它们的引用,也无法证明变异和重新分配之间的区别。

谈论
int
s的不变性很尴尬,因为变异不是容器的东西的想法对我们大多数人来说都没有意义。让我们来谈谈弦

下面是一个字符串,用Python表示:

s = "abc"
字符串是包含一定数量的单个字符的容器:这里是
a
b
c
。如果我想将第二个字符更改为
d
,我可以尝试:

s[1] = 'd'
它将失败并出现
类型错误
。我们说字符串在Python中是不可变的,因为没有任何操作会改变现有字符串。当然,有很多操作将执行某些操作并创建新字符串,但现有字符串是一成不变的

这里有几个优点。一个是它允许插入:有时当字符串需要分配时(由解释器自行决定),CPython会注意到已经分配了相同的字符串,只需重用相同的
str
对象。当字符串是不可变的时,这是最简单的,否则,您必须对以下问题采取措施:

s = "abc"
t = "abc"   # this reuses the same memory, as an optimization
s[0] = "x"  # oops!  now t has changed, too!
Interning在Python和支持运行时反射的类似语言中特别有用:它必须在运行时知道每个函数和方法的名称,而且许多方法都有内置名称,如
\uuuuuuu init\uuuu
(constr
int x = 3;
x = 4;  // Mutates x
x++;    // Mutates x
int x = 3;
int *p = x;   // Pointer to original entity
x = 4;
printf("%d\n", *p);   // 4