Java 为什么不可变的整数类可以重置其值?

Java 为什么不可变的整数类可以重置其值?,java,Java,我之前读过,包装器类都是不可变的。不可变意味着该值不能更改。下面我尝试了这个简单的示例,它可以粘贴到任何主方法中。首先,我创建一个整数,它将值5包装起来。不可变意味着它们不能更改,所以为什么我可以将I设置为89。我认为这是因为它在(我)所指的地方发生了变化,但我不确定为什么会这样 在我的下一个小例子中,我创建了一个x的整数,如果我尝试更改它,它将抛出一个错误。在这个特定的情况下,x似乎是不可变的,但在(i)变量的情况下则不是 似乎我可以随时更改(I)的值,所以实际上,不带final关键字的整数不

我之前读过,包装器类都是不可变的。不可变意味着该值不能更改。下面我尝试了这个简单的示例,它可以粘贴到任何主方法中。首先,我创建一个整数,它将值5包装起来。不可变意味着它们不能更改,所以为什么我可以将I设置为89。我认为这是因为它在(我)所指的地方发生了变化,但我不确定为什么会这样

在我的下一个小例子中,我创建了一个x的整数,如果我尝试更改它,它将抛出一个错误。在这个特定的情况下,x似乎是不可变的,但在(i)变量的情况下则不是

似乎我可以随时更改(I)的值,所以实际上,不带final关键字的整数不是不变的????如果我可以设置为89,那么对我来说,这个变量似乎可以更改

我已经读过其他关于这个的帖子,我仍然不确定为什么我可以换成另一个变量。此外,在编写代码时,声明基元类型的最佳方法是什么。为什么不一直使用包装类来创建变量呢

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;
使用所有包装类来声明变量:(这会比使用基本变量类型声明这些变量更好吗)


您将两件事混为一谈:更改“对象”本身的值和更改引用指向的对象。说
i=89
只是将变量
i
指向一个新对象;它不会更改最初由
i
指向的
Integer
对象


带有
final
的预挂起变量声明只是确保禁止重新赋值,它绝不是对它所指向的对象的可变/不可变性的声明。可能是离题了,但我个人认为这篇文章读得不错。

你把两件事混为一谈:更改“对象”本身的值和更改引用点的对象。说
i=89
只是将变量
i
指向一个新对象;它不会更改最初由
i
指向的
Integer
对象


带有
final
的预挂起变量声明只是确保禁止重新赋值,它绝不是对它所指向的对象的可变/不可变性的声明。也许是离题了,但我个人认为这篇文章读得不错。

当你调用
I=89
,则不更改存储在内存中的
整数
对象的值。相反,您将一个全新的
int
赋值为
i
。所以不变的规则没有被打破


请记住,
i
只是指向
整数的引用,而不是实际的
整数本身。

调用
i=89
,则不更改存储在内存中的
整数
对象的值。相反,您将一个全新的
int
赋值为
i
。所以不变的规则没有被打破


请记住,
i
只是一个指向
整数的引用,而不是实际的
整数本身。

是的,看起来整数确实在变化,但第3行发生的一切是编译器将其转换为
i=new Integer(89)
。如果你想看,你可以

Integer i1 = i;
i = 83;
println(i); \\ prints out the original value 5
println(i1); \\ prints out a new value, 83
当您声明某个内容为final时,您不能更改变量的定义,尽管您仍然可以对其中的任何内容进行变异


如果可以避免使用包装器对象,则不应使用包装器对象,因为它们的效率比原语低一点,并且会占用一些额外的字节

是的,看起来整数确实在变化,但第3行上发生的一切就是编译器将其转换为
i=new integer(89)
。如果你想看,你可以

Integer i1 = i;
i = 83;
println(i); \\ prints out the original value 5
println(i1); \\ prints out a new value, 83
当您声明某个内容为final时,您不能更改变量的定义,尽管您仍然可以对其中的任何内容进行变异


如果可以避免使用包装器对象,则不应使用包装器对象,因为它们的效率比原语低一点,并且会占用一些额外的字节

那么,您如何打破Java整数的不变规则呢?正如您所说,您不能。对不起,如果我暗示这是可能的。无论何时对
整数执行任何类型的操作(加法、位移位等),都会返回一个新值。这回答了你的问题吗?有点。让我举个例子。如果我有整数a=新整数(100);那么a的值是100。我无法将其重置为50,因为整数是不可变的,但是如果我将a的值设置为我前面声明的int值,那么我可以更改,但不会影响a所指的整数。所以这实际上是关于不变性的一部分。正确。我可以将I更改为任何整数值,因为它是基元,但我不能直接使用a.valueOf(100)更改整数值,但a.valueOf(I)将起作用,因为我可以更改I的值,这将间接更改整数值a。“那么a的值是100”…否
a
现在指的是一个值为100的
整数。像
A
这样的引用本身没有值;它指向内存中具有值的对象。至于你的第二条评论,
Integer.valueOf()
不会影响你调用它的
Integer
(既然它是
静态的
,你实际上应该把它称为
Integer.valueOf(100)
,永远不要
a.valueOf(100)
)。那么你怎么打破Java整数的不变规则呢?正如你所说的,你不能。对不起,如果我暗示这是可能的。无论何时对
整数执行任何类型的操作(加法、位移位等),都会返回一个新值。这回答了你的问题吗?有点。让我举个例子。如果我在中有整数a=new