java整数引用

One*_*mir 9 java

我有一个问题.

public class Jaba {

    public static void main(String args[]) {
        Integer i = new Integer(0);        
        new A(i);
        System.out.println(i);
        new B(i);
        System.out.println(i);
        int ii = 0;        
        new A(ii);
        System.out.println(ii);
        new B(ii);
        System.out.println(ii);    
    }

}

class A {

    public A(Integer i) { ++i; }

}

class B {

    public B(int i) { ++i; }

}
Run Code Online (Sandbox Code Playgroud)

在我看来,将int\Integer作为Integer传递给函数并在该引用上生成++应该更改底层对象,但在所有情况下输出都是0.这是为什么?

Aln*_*tak 12

大多数类Integer派生自Java的抽象Number类是不可变的,即一旦构造,它们只能包含那个特定的数字.

这样做的一个有用的好处是它允许缓存.如果你打电话:

Integer i = Integer.valueOf(n);
Run Code Online (Sandbox Code Playgroud)

用于-128 <= n < 127代替:

Integer i = Integer.new(n)
Run Code Online (Sandbox Code Playgroud)

你得到一个缓存的对象,而不是一个新的对象.这样可以节省内存并提高性能.

在后一个带有裸int参数的测试用例中,您所看到的只是Java的变量是如何通过值而不是通过引用传递.


Jar*_*iuk 5

@Alnitak - >正确.并添加这里真正发生的事情.由于自动装箱而产生的++ i就是这样的:

int val = Integer.intValue(); ++val;
Run Code Online (Sandbox Code Playgroud)

并且val不存储在任何地方,因此增量丢失.


Paŭ*_*ann 3

正如其他答案中所述,Java 仅执行按值调用,并且++运算符仅影响变量,而不影响对象。如果要模拟按引用调用,则需要传递一个可变对象(例如数组),并修改其元素。

Java API 有一些专门用于此目的的对象,例如java.util.concurrent.atomic.AtomicInteger(它还可以在多个线程上工作)和org.omg.CORBA.IntHolder(用于通过 CORBA 机制进行远程调用的引用调用)。

但您也可以简单地定义自己的可变整数:

class MutableInteger {
    public int value;
}


class C {
   public C(int[] i) {
       ++i[0];
   }
}
class D {
   public D(MutableInteger i) {
       ++i.value;
   }
}
class E {
   public E(AtomicInteger i) {
       i.incrementAndGet();
   }
}
public class Jaba {
    public static void main(String args[]) {

        int[] iii = new int[]{ 0 };
        System.out.println(iii[0]);
        new C(iii);
        System.out.println(iii[0]);
        MutableInteger mi = new MutableInteger();
        System.out.println(mi.value);
        new D(mi);
        System.out.println(mi.value);
        MutableInteger ai = new AtomicInteger(0);
        System.out.println(ai);
        new E(ai);
        System.out.println(ai);
    }
}
Run Code Online (Sandbox Code Playgroud)