6

Lets say this is the C++ code:

void change(int& x){
    x++;
}

or

void change2(int* a){
    *a++;
}

Both will change the global x, right?

So how can I do something like that in java?
Specifically, I want to point to a Vector object

But since Java has no pointers, I'm not sure what to do.
From searching the internet I saw people saying that Java does that in some other way, but I haven't found any real example.

Thanks for help!

SmRndGuy
  • 1,719
  • 5
  • 30
  • 49
  • Java is always pass by value. – Martijn Courteaux Apr 15 '12 at 08:33
  • The answer is likely, "you can't" - but start by give us the relevant Java code ... – Greg Kopff Apr 15 '12 at 08:36
  • 1
    possible duplicate of [How to pass by reference in Java](http://stackoverflow.com/questions/5614562/how-to-pass-by-reference-in-java) – Ferdinand Beyer Apr 15 '12 at 08:40
  • possible duplicate of [Is Java pass by reference?](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) – Greg Hewgill Apr 15 '12 at 08:41
  • So, you just want a global [Vector](http://docs.oracle.com/javase/6/docs/api/java/util/Vector.html) that you can keep stuff in? (What kind of objects?) Or is it something else that you're ultimately trying to do? – Jonik Apr 15 '12 at 08:58
  • 3
    Your second example does not make any sense. You are assigning the address of a global variable to a local pointer variable, then increment the pointer. This will neither effect the global `x` nor the argument `a` on the caller's side. – Ferdinand Beyer Apr 15 '12 at 10:55

6 Answers6

13

In Java, instead of pointers you have references to objects. You cannot pass a primitive type by reference, but you can wrap a primitive type inside an object and then pass a reference to that object.

Java provides the type Integer which wraps int, however this type is immutable so you cannot change its value after construction. You could however use MutableInt from Apache Commons:

void change(MutableInt x) {
    x.increment();
}

The change to x will be visible to the caller.


Specifically, I want to point to a Vector object

When you write Vector v = ...; you are assigning a reference to a vector to the variable v. A reference in Java is very similar to a pointer. References are in fact implemented internally using pointers.

Java uses pass by value. When you pass a vector to a method, you are actually copying a reference to that vector. It does not clone the vector itself. So passing a reference in Java is very similar to passing a pointer in C++.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • What I don't like about this is that it gives the impression that you need a 3rd party lib to do something extremely basic in Java. I'm pretty sure that OP does **not** really need MutableInt or anything else from Apache Commons; instead, he'd just need to learn idiomatic Java. Admittedly the question is hard to answer better, as it isn't clear what he *really* wants his code to do. – Jonik Apr 15 '12 at 09:15
  • I also do not like that this is the accepted answer. See http://stackoverflow.com/questions/5614562/how-to-do-the-equivalent-of-pass-by-reference-for-primitives-in-java/5614630#5614630 for a thorough explanation of 4 ways to do this, without importing any third party library. Or see dash1e's answer for a common way of doing this. – ToolmakerSteve Jul 23 '14 at 03:49
4

With Java you cannot pass primitive types like int by reference, they are passed only by value.

The only things you can do is to find artifices to do that, because instead Objects are passed by reference. Here two examples.

Use an array of single value, like this

int[] value = new int[1];
value[0] = 2;

// call a method
obj.setValue(value);

// and in setValue
public void setValue(int[] value) {
  value[0] = 5;
}

Or second approach use an holder class:

public class Holder<T> {
  public T value;
  public Holder(T value) {
    this.value = value;
  }
}

// then use it in this way
Holder<Integer> h = new Holder<Integer>(2);

obj.setValue(h);

// and in setValue
public void setValue(Holder<Integer> h) {
  h.value = 5;
}

In this case I use an holder class implements with generics but you can have a simple holder too, only for integer. For example:

public class IntHolder {
  public int value;
  public IntHolder(int value) {
    this.value = value;
  }
}
guness
  • 6,336
  • 7
  • 59
  • 88
dash1e
  • 7,677
  • 1
  • 30
  • 35
  • dear SmRndGuy, this is the answer you are looking for. (PS: I didnt know about Holder class, so thank you dash1e .) – guness Apr 15 '12 at 09:04
  • @bluebrain pay attention, is not a Java standard class, you have to write your Holder by yourself, but it is very simple. Maybe, sometimes, you can find Holders in different libraries because it is an usual way to solve that problem. – dash1e Apr 15 '12 at 09:06
  • That generic `Holder` class a nice way of doing a "wrapper". – Spoike Apr 15 '12 at 09:22
1

Java always passes by value and there are no global variables as in the C++ sense. So if you want to do the same as in C++ you need to return the new value.

Thusly:

public int change(int x) {
    return ++x;
    // or 
    // return x + 1;
}

To test it:

int x = 2;

change(x);

System.out.println(x); // returns 2

x = change(x);

System.out.println(x); // returns 3

So it doesn't make any sense to let the method be called change, it is more sensible along the lines of calculateThisInt.


Java does pass objects by value. But as Mark Byers mentions the Integer class is immutable and you could use MutableInt from Apache Commons library. To describe how this works you could implement it yourself for your example:

public class MyInt() {

    public int i;

    public void setInt(int i) {
        this.i = i;
    }

    public int getInt() { 
        return this.i; 
    }

    public int increment() {
        this.i++;
    }

}

You need to change your change function to have the above MyInt object as argument:

public void change(MyInt i) {
    i.increment();
}

Usage:

MyInt x = new MyInt();
x.setInt(2);

change(x);

System.out.println(x.getInt); // returns 3

In your case you want to change a Vector object...

public void changeVector(Vector v) {
    // anything you do with 'v' will change it even
    // for the scope that called this method
}

// Usage:
Vector v = new Vector();
changeVector(v);
// v should be changed after calling change vector method

Hope this all makes sense.

Community
  • 1
  • 1
Spoike
  • 119,724
  • 44
  • 140
  • 158
  • you need to use return ++x; instead of return x++; – Chris Apr 15 '12 at 08:47
  • Objects are not passed by reference in Java. The reference to an object is passed by value. – Hauke Ingmar Schmidt Apr 15 '12 at 09:15
  • @his: Okay, I got concepts mixed up. I guess I need more coffee this morning. :-P – Spoike Apr 15 '12 at 09:20
  • Still a little misleading: "Java does pass objects by value". As there are no value objects in Java this is not quite exact. "Java does pass objects _references_ by value" would be better. – Hauke Ingmar Schmidt Apr 15 '12 at 09:39
  • IMHO "Java does pass objects by value" is more confusing than the pre-edit version "Java passes objects by reference". To a casual reader "pass by value" makes it sound like any changes made to the fields on an object, within a method, would not affect the original object, as if a COPY of the object were sent to the method. Personally, I would drop that sentence. Also drop "But" from the following sentence. The important point is that Integer is IMMUTABLE, and what is needed is a MUTABLE instance. – ToolmakerSteve Jul 23 '14 at 04:01
0

While you can't replace an object that's been passed to a function, you can change its state by altering fields directly or calling methods. If you need something like a pointer to a primitive, wrap it in an object. To follow your code, you could do this:

public class IntPointer {
    public int value;
    public IntPointer(int value) {
        this.value = value;
    }
}

Then elsewhere you could say:

public static void change(IntPointer ipoint) {
    ipoint.value++;
}
public static void main(String[] args) {
    IntPointer a = new IntPointer(10);
    change(a);
}

This might seem a bit awkward, but it hasn't come up for me as often as you'd think. I'd be more likely to do something like this:

public class ABPair {
    private int a = 0;
    private int b = 0;
    public static void changeA() {
        a++;
    }
    public static void changeB() {
        b++;
    }
}

So that elsewhere I can say:

public static void main(String[] args) {
    ABPair ab = new ABPair();
    if (ACondition) {
        ab.changeA();
    }
}

In other words, my data tends to already be wrapped in some sort of object, and I tend to use the data object's methods to mediate any changes.

maybeWeCouldStealAVan
  • 15,492
  • 2
  • 23
  • 32
0

Both will change the global x, right?

So how can I do something like that in java? Specifically, I want to point to a Vector object

The question is somewhat vague, but I got the impression that you ultimately want a global Vector that you can keep stuff in?

Many ways to do that, but one of the simplest is to have a static field in a class, with public static methods for accessing it. (Or simply a public static field which is accessed directly, but that really wouldn't be idiomatic in Java.)

public class Foo {
    private static List<Integer> globalVector = new Vector<Integer>();

    public static void add(int number){
         globalVector.add(number);
    }

    // ... plus whatever other accessors to the global list that you need 
}

Anywhere else in code:

Foo.add(23); // modifies the global vector

(Btw, Vector is kinda obsolete, and typically we'd use ArrayList in its place now. As the Javadoc says, it's been retrofitted to implement the List interface, which I also used in the example.)

Jonik
  • 80,077
  • 70
  • 264
  • 372
  • **Disclaimer**: I may have totally misinterpreted what OP wanted, and will delete this if that turns out to be the case. The question really should be clearer on what it is that OP actually wants to achieve with his code. – Jonik Apr 15 '12 at 09:35
0

Java supports what it calls "references". References act alot like pointers in C/C++-like languages. They don't act the same way "references" work in those languages.

The major differences between a pointer in C and a reference in Java are:

You can't do pointer arithmetic in Java (i.e. you can't "add" or "subtract" from a Java reference, you can only dereference it or compare it with another one). You can't cast it to an incompatible type: Java is strongly type-safe, you can't "re-interpret" the bytes in memory as some other object. For some uses of pointers this has no real effect (for example linked lists work pretty much the same in both languages), for others the difference is quite major (arrays in C are just fancy pointer arithmetic, in Java they work quite differently).

So in a way Java references could be called "restricted pointers".

Usama Tahir
  • 1,235
  • 12
  • 14