简体   繁体   English

为什么不变类Integer可以重置其值?

[英]Why can the immutable class Integer have its value reset?

I was reading earlier that wrapper classes are all immutable. 我之前读过包装器类都是不可变的。 Immutable means that the value cannot be changed. 不可变表示该值不能更改。 Below I tried this simple example that can just be pasted in to any main method. 下面我尝试了这个简单的示例,可以将其粘贴到任何主要方法中。 first I create a Integer that wraps the value five. 首先,我创建一个包装值5的Integer。 Immutable means that they cannot be changed so why can I set I to 89. I think that it is because it changes where (I) points to but I am not certain why this is the case. 不可变意味着它们不能更改,所以我为什么要将I设置为89。我认为是因为它更改了(I)指向的位置,但我不确定为什么会这样。

In my next little example i create an Integer of x which will throw an error if I try and change it. 在我的下一个小示例中,我创建一个x的整数,如果尝试更改它将会抛出错误。 The x seems to be immutable in this specific case but not in the case of the (i) variable. 在这种特定情况下,x似乎是不可变的,但在(i)变量的情况下,x似乎是不变的。

It seems that I can change the value of (i) whenever I want to so in reality Integer without the final keyword is not immutable???? 似乎我可以随时更改(i)的值,实际上,没有final关键字的Integer不是不可变的吗? If i can be set to 89 then to me this seems that the variable can be changed. 如果我可以设置为89,那么对我来说似乎可以更改该变量。

I have read other post on this and I still am not certain why i can be changed to another variable. 我已经读过其他文章,我仍然不确定为什么可以将我更改为另一个变量。 Also in writing code what is the best way to declare primitive types. 同样在编写代码时,什么是声明基本类型的最佳方法。 Why not use the wrapper classes all of the time to create variables. 为什么不一直使用包装器类来创建变量。

int y = 5; 
Integer i = new Integer(y);
i = 89;
final Integer x = Integer.valueOf(5);

System.out.println("Integer:(i) " + i.intValue());
System.out.println("Integer:(i) " + i.byteValue());

System.out.println("Integer:(x) " + x.intValue());;
System.out.println("Integer:(x) " + x.byteValue());;

i = i - 5;

Using all wrapper classes to declare variables: (Would this be better than declaring these variable with the primitive variable types) 使用所有包装器类来声明变量:(这比用原始变量类型声明这些变量要好)

Integer a = new integer(MyNewValue);
Integer b = new integer(MyNewValue);
Integer c = new integer(MyNewValue);
Integer d = new integer(MyNewValue);
Float   fa = new integer(MyNewValue);

You are conflating two things: changing the value of an "object" itself and changing the object a reference points to. 您正在混淆两件事:更改“对象”本身的值和更改引用指向的对象。 Saying i = 89 just points the variable i to a new object; i = 89只是将变量i指向一个新对象。 it doesn't change the Integer object which originally was pointed to by i . 它不会更改i最初指向的Integer对象。

Pre-pending variable declarations with final just ensures that reassigned is prohibited, it is in no way a declaration of the mutability/immutability of the object it points to. 在变量声明前加上final只是为了确保禁止重新分配,它绝不是声明它所指向的对象的可变性/不可变性的声明。 Maybe off-topic, but I personally think the article Java is Pass-by-Value, Dammit! 也许是题外话,但是我个人认为Java是价值传递,该死! is a good read. 是一本好书。

When you call i = 89; 当你打电话给i = 89; , your not changing the value of the Integer object stored in memory. ,则无需更改存储在内存中的Integer对象的值。 Instead, you're assigning a brand new int with value 89 to i . 相反,您要为i分配一个值为89的全新int So the immutable rule isn't being broken. 因此,不变的规则没有被打破。

Remember that i is simply a reference that points to the Integer , not the actual Integer itself. 请记住, i只是指向Integer的引用,而不是实际的Integer本身。

Yes, it does look like the integer is changing, but all that is happening on line 3 is its being converted to i = new Integer(89) by the compiler. 是的,它看起来确实在改变整数,但是第3行发生的所有事情都是由编译器将其转换为i = new Integer(89) If you wanted to see, you could do 如果你想看,你可以做

Integer i1 = i;
i = 83;
println(i); \\ prints out the original value 5
println(i1); \\ prints out a new value, 83

When you declare something as final, you cannot change the definition of the variable, though you can still mutate anything inside it. 当您将某些内容声明为final时,尽管仍可以对变量中的任何内容进行突变,但无法更改变量的定义。 JavaRanch has a very nice analogy to help JavaRanch有一个很好的类比来帮助您

You should not use wrapper objects when you can avoid it because they are a small amount less efficient to than primitives and take up a few extra bytes. 可以避免使用包装对象时,不要使用包装对象,因为包装对象的效率比原始对象低,并且占用一些额外的字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM