9

I've got a question.

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; }

}

To my mind passing an int\Integer as Integer to a function and making ++ on that reference should change the underlying object, but the output is 0 in all the cases. Why is that?

4 Answers 4

12

Most of the classes such as Integer that derive from Java's abstract Number class are immutable., i.e. once constructed, they can only ever contain that particular number.

A useful benefit of this is that it permits caching. If you call:

Integer i = Integer.valueOf(n);

for -128 <= n < 127 instead of:

Integer i = Integer.new(n)

you get back a cached object, rather than a new object. This saves memory and increases performance.

In the latter test case with a bare int argument, all you're seeing is how Java's variables are passed by value rather than by reference.

Sign up to request clarification or add additional context in comments.

1 Comment

Actually, the Number class simply is abstract and stateless - and there are subclasses that are mutable (AtomicInteger and AtomicLong are such ones, and one also could define new custom ones).
5

@Alnitak -> correct. And to add what really happens here. The ++i due to autoboxing works like that:

int val = Integer.intValue(); ++val;

and val is not stored anywhere, thus increment is lost.

Comments

3

As said in the other answers, Java does only call-by-value, and the ++ operator only effects a variable, not an object. If you want to simulate call-by-reference, you would need to pass a mutable object, like an array, and modify its elements.

The Java API has some specialized objects for this, like java.util.concurrent.atomic.AtomicInteger (which additionally also works over multiple threads), and org.omg.CORBA.IntHolder (used for call-by-reference for remote calls by the CORBA mechanism).

But you can also simply define your own mutable integer:

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);
    }
}

1 Comment

java only does call by sharing
0

If you want to use reference parameter then try this.

IntHolder http://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/IntHolder.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.