让方法修改引用而不是新对象

时间:2014-07-26 13:23:09

标签: java object methods reference

我打赌这个问题已经回答了,但我不知道如何用简单的语言解释这个问题,在谷歌上找到一个简单的回答 - 我很抱歉!

这是我的测试代码:

public class test {
public static void increase(Integer i){
    i++;
}

public static void main(String[] args){
    Integer x = new Integer(10);
    increase(x);
    System.out.println(x);
}

}

我有一个Integer x,想通过void-method"增加(..)"来修改它。 由于Integer是一个Object,x是指向该对象的指针。 我想"增加(..)"修改整数本身,所以"我"是指" x"确实。但是如果我看一下print(x)(" 10")我假设该方法创建了一个新的Integer,内容为" x"。

我希望有人能理解我......

我需要的是什么?

我正在尝试使用多个线程来总结从1到" n"的数字。 我创建了一个Class" MyThread"得到lowerLimit和upperLimit来总结间隔,得到一个"结果" (但作为参考 - 不是新对象),其中添加了间隔的数量。

最诚挚的问候 Tak3r07

4 个答案:

答案 0 :(得分:3)

有三种方法可以做到这一点。

public class test {
public static void increase(AtomicInteger i){
    i.getAndIncrement()
}

public static void main(String[] args){
    AtomicInteger x = new AtomicInteger(10);
    increase(x);
    System.out.println(x);
}
}

public class test {
public static void increase(int[] i){
    i[0]++;
}

public static void main(String[] args){
    int[] x = { 10 };
    increase(x);
    System.out.println(x[0]);
}
}

或使用Integer

public class test {
public static void increase(Integer[] i){
    i[0]++;
}

public static void main(String[] args){
    Integer[] x = { 10 };
    increase(x);
    System.out.println(x[0]);
}
}
  

出于兴趣,你能解释一下为什么会这样吗?我认为java严格按价值传递?

Java是按值传递的。引用按值传递,但这是浅而不是深拷贝。即您无法更改引用,但您可以更改引用的对象。

您无法直接使用Integer执行此操作,因为它是不可变的,因此您无法更改任何内容。传递对可变对象的引用,您可以更改它。

答案 1 :(得分:2)

Integer这样的String类和其他原始包装类是不可变的,这意味着它们的值不能改变,所以每当你试图改变它们的值时,你实际上是在创建一个它们的新实例。您可以使用AtomicIntegerAtomicLongAtomicDouble ...来实现此目的。

答案 2 :(得分:2)

e++形式的表达式是

的简写
E old = e;
e = (E) (old + 1);
return old;

其中Ee的类型。

也就是说,你的表达式等同于

i = (Integer) (i + 1);

通过计算i + 1,创建(或重用)Integer对象来保存该值,并将该对象的引用存储在变量i中来评估。原始Integer对象未被修改,调用者仍然引用该原始对象,因此看到原始值。

要解决此问题,您可以返回对新Integer对象的引用,并要求调用者存储它,或者将引用传递给支持更改值的类的对象。唉,Integer不是这样的类,因为一旦创建了对象,它的值就无法改变。有关合适课程的例子,请参阅彼得和布拉杰的答案。

答案 3 :(得分:1)

创建一个可以满足您需求的单独类:

示例代码:

public class MyInteger {
    int value;

    public MyInteger(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public void increase() {
        value++;
    }

    @Override
    public String toString(){
        return String.valueOf(value);
    }

}

....

public static void main(String[] args){

    MyInteger x = new MyInteger(10);
    x.increase();
    System.out.println(x.getValue());  // print 11
    System.out.println(x);             // print 11

}