当它是像更改数组值这样的参数时,如何更改整数值? [复制]

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 中的参数ii 变量,只是它们在方法开始时具有相同的值。 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);

【讨论】:

这对我来说是最好的答案

以上是关于当它是像更改数组值这样的参数时,如何更改整数值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

语言更改时调整表单大小

通过javascript将参数传递给动作不会传递整数值

如果组件用于多个输入,如何更改输入值

C# 中的 SqlBulkCopy 类正在更改数值

Numpy:如何按整数值缩放整数数组?

Extjs:加载商店时更改参数值