当它是像更改数组值这样的参数时,如何更改整数值? [复制]
Posted
技术标签:
【中文标题】当它是像更改数组值这样的参数时,如何更改整数值? [复制]【英文标题】:How can I change Integer value when it is an argument like change array's value? [duplicate] 【发布时间】:2014-11-28 21:36:36 【问题描述】:public static void main(String[] args)
Integer i = new Integer(0);
int[] arr = 1;
p1(i);
p2(arr);
System.out.println(i);
System.out.println(arr[0]);
public static void p1(Integer i)
i = 2;
public static void p2(int[] i)
i[0] = 2;
//输出:0, 2
如何更改 i 的值,就像更改 arr 的值一样?
【问题讨论】:
【参考方案1】:您不能在p1
方法中更改main
中变量i
的值,因为参数是按值传递的:p1
中的参数i
与i
变量,只是它们在方法开始时具有相同的值。 Java 总是使用按值传递的语义——但是当参数类型是一个类时,它是一个按值传递的引用。
事实上,您也没有更改arr
的值——它是对与以前相同的数组的引用,但数组中的值in 已更改。这就是 Integer
无法做到的,因为 Integer
是不可变类型。
如果你想要一个像Integer
这样的可变类,你可以改用AtomicInteger
:
public static void main(String[] args)
AtomicInteger i = new AtomicInteger(0);
modify(i);
System.out.println(i);
private static void modify(AtomicInteger x)
x.set(2);
我通常不会这样做,但是 - 我通常尽量不修改方法参数引用的对象。相反,我编写了计算单个结果并返回该结果的方法。
【讨论】:
这不是问题的答案,因为 AtomicInteger 根本不是整数。而你回答错了。参数不是按值传递的。它是通过引用传递的,因为 this 是整数对象(不是原始 int)。 @walkeros:不,它真的不是通过引用传递的,因为在Java中没有任何东西通过引用传递。请阅读javadude.com/articles/passbyvalue.htm 或关于这个主题的数百个问题中的一些。我已经解释过 OP 要求的内容不能直接完成,所以我给出了一个 similar (但可变)类型的答案。 任何布尔类型,如 atomicinteger? @cow12331:AtomicBoolean
?
@walkeros: 不,它不像是通过引用传递一样 - 因为否则在方法中更改i
会修改调用者的变量。 (这就是按引用传递的全部内容。)请注意,我没有说对象是按值传递的——我说 reference 是按值传递的。恐怕你是误导 - 并且不准确 - 在这里,我声称 Java 使用传递引用。将此与 C# 之类的语言进行比较,后者默认情况下类似于 Java,但也允许使用 ref
修饰符进行引用传递。【参考方案2】:
简单地说:你不能,因为Integer
是不可变的,你只能通过值获取对象地址,所以交换整个对象是不可能的,因为方法完成后,旧对象会被重新分配。
【讨论】:
【参考方案3】:只能通过使用一些“技巧”。你可以这样做:
public static void p1(Integer curInt)
Field field = curInt.getClass().getDeclaredField("value"); // Integer stores the real value in private field "value"
field.setAccessible(true);
field.set(curInt, 2);
【讨论】:
在这种情况下使用反射是绝对不合适的。 @Dimitry:你为什么这么认为?它并不漂亮。没错,但这就是反思的目的。 应该使用反射,其他什么都不能使用。在那里,Integer
可以替换为 AtomicInteger
或者 OP 可以传递数组(不如只使用一些可变的国王 Integer
,但也可能)。
很多时候,反射以完全合理的方式很有用。这不是那些时代之一。哎呀,如果您传递了一个小的int
的自动装箱结果,情况会变得更糟,因为这样会在每次自动装箱相同的值时使用变异的(污染的!)对象。像这样的代码应该带有比“仅使用一些黑客”更强烈的健康警告...
@walkeros:我宁愿写比 OP想 听到的更多内容,而是告诉他们他们需要听到的一切,而不是实际邀请某人做一些非常危险的事情,但没有说明风险。【参考方案4】:
您可以使用AtomicInteger
,它允许更改,而不是Integer
:
public static void main(String[] args)
AtomicInteger i = new AtomicInteger(0);
p1(i);
System.out.println(i);
public static void p1(AtomicInteger i)
i.set(2);
【讨论】:
这对我来说是最好的答案以上是关于当它是像更改数组值这样的参数时,如何更改整数值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章