Mick
Mick

Reputation: 7957

pass by reference/value - simple example

I know this issue has been addressed many times - but my Java/C++ knowledge is so weak I can barely understand the answers :-( ... what I'd really like is just a super simple example.

In C++ I could write the following:

void func()
{
  int x = 3;
  add_one(x);
  // now x is 4.
}
void add_one(int &var)
{
  var++;
}

What I'd like to see now is the simplest way to achieve the same effect with java.

Upvotes: 8

Views: 10165

Answers (6)

hvgotcodes
hvgotcodes

Reputation: 120318

You can't directly. The closest you can get is to put the value in an object, and pass the reference (by value, so the reference gets copied) into the method.

void func()
{
  int x = 3;
  int[] holder = [x];
  add_one(holder);
  // now holder[0] is 4.  x is still 3.
}

// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
    container[0]++;
}

Here I use an array, but the wrapper can be any object.

Upvotes: 10

Jabrown207
Jabrown207

Reputation: 225

public int getOneMore(int val) {
  return val + 1;
}

Upvotes: -3

pb2q
pb2q

Reputation: 59667

In java method arguments are pass-by-value, and can't be changed in the function. You must wrap the int - or any other primitive type - in an Object or an array. Passing an Object or an array as a method argument passes a reference which can be used to modify the object.

Java already has Object based wrappers for primitive types, e.g. Integer, but these are immutable by design. Some libraries provide mutable versions of these wrappers; you can also create your own:

public class MutableInt
{
    private int val;

    public MutableInt(int val)
    {
        this.val = val;
    }

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

    public int getValue()
    {
        return this.val;
    }
}

void func()
{
    int x = 3;
    MutableInt wrapper = new MutableInt(x);
    add_one(wrapper);
}

void add_one(MutableInt arg)
{
    arg.setValue(arg.getValue() + 1);
}

Upvotes: 3

Matt
Matt

Reputation: 11815

As you can see from the other answers, Java is purely pass by value. Objects are passed by what some call "value-reference". Since an object in java is simply a pointer reference, you can think of the "value" as the address where the object lives on the heap. So when you make a method call, you're copying the "value", aka address, to the method parameter:

Object x = new Object();
foo(x);

During object creation

Heap --> allocate Object (5000)

Variable Declaration

Stack --> allocate local variable (1000)

Variable Assignment

Stack address 1000 set to 5000 (to point to object instance)

So you can see that there are two separate memory allocations here. The "value" of the variable is considered to be it's address on the heap.

Method Call

Stack --> allocate method parameter 8000

Stack address 8000 set to same value as passed parameter 5000

This is why if you reassign an object instance in a method, it does not propagate back to the caller. You would have changed the heap location at stack location 8000. And the calling method's stack location 1000 still has the value 5000 (the original object instance).

Think of it like this in C:

void method(myobject * obj);

You can certainly change fields of "obj", and you can do this locally:

obj = new myobject();

But the caller will still see the original value it passed.

Java has no analog to the & reference operator.

And there are built in classes which can be used for the your purposes. AtomicInteger, AtomicLong, etc... are mutable, though you may suffer a performance hit due to synchronization involved.

I would recommend a generic ValueHolder class to account for all situations where you want to simulate pass by reference:

public class ValueHolder<T> {
    private T value;
    // getter/setter/constructor
}

Upvotes: 0

Moataz Elmasry
Moataz Elmasry

Reputation: 2519

Java allows copy by reference for objects and copy by vlaue for primitive types (int,float,etc..). This is so by default and is not subject to change. If you need to change the value of an int inside a function, then you can use the class Integer for example

Upvotes: -3

duffymo
duffymo

Reputation: 309018

You cannot do this. Java is only pass by value. Primitives are obvious, but the thing that's passed for objects is a reference, not the object itself.

Upvotes: 2

Related Questions