12

I want to use reference in Java but I don't know how! for example in C++ we write:

void sum(int& x)
{
    ...
}

but in Java & sign is a compiler error! please help me to understand references in Java.

Esko
  • 29,022
  • 11
  • 55
  • 82
Mahdi_Nine
  • 14,205
  • 26
  • 82
  • 117
  • @Esko, except you are not supposed to edit posts solely to make minor cosmetic fixes (such as correcting a typo). I find it depressing that @skaffman posted his comment in that "tone" and that 6 more people up voted it as helpful. – Tim Bender Jan 17 '11 at 13:27
  • @Tim: Actually I do remember reading the complete opposite of what you just said from the official blog and meta several times. As I see it, fixing typos and grammar is endorsed since sometimes it makes understanding the question itself a lot easier for others. – Esko Jan 17 '11 at 15:03
  • 1
    @Esko, you're right, but now I'm more depressed. – Tim Bender Jan 17 '11 at 15:19
  • 1
    possible duplicate of [Is Java pass by reference?](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) – KV Prajapati Jan 17 '11 at 15:21
  • http://stackoverflow.com/questions/40480/is-java-pass-by-reference see the above post – fmucar Jan 17 '11 at 12:11

4 Answers4

14

Objects are passed by reference by default Objects are accessed by reference, but there is no way to create a reference to a primitive value (byte, short,int, long). You either have to create an object to wrap the integer or use a single element array.

public void sum(int[] i){
   i[0] = ...;
}

or

public void sum(MyInt i){
   i.value = ...;
}
public class MyInt{
   public int value; 
}

for your example something like the following could work

public int sum(int v){
   return ...;
}

or

public int sum(){
   return ...;
}

Update:

Additional/Better description of object references:

Java Objects are always accessed by a reference. Like the primitive types this reference is passed by value (e.g. copied). Since everything a programmer can access in java is passed by copying it (references, primitives) and there is no way to create a reference to a primitive type, any modification to a method parameter (references, primitives) only affects the local copy within the method. Objects can be modified within a method since both copies of the reference (local and other) still point to the same object instance.

example:

Modify a primitive within method, this only affects the internal copy of i and not the passed value.

void primitive(int i){
  i = 0;
}

Modify a reference within method, this only affects the internal copy of ref and not the passed value.

 void reference(Object ref){
    ref = new Object();//points to new Object() only within this method
 }

Modify an object, visible globally

void object(List l){
   l.add(new Object());//modifies the object instead of the reference
}

Both the array and MyInt above are based on the modification of an object.

kiedysktos
  • 3,910
  • 7
  • 31
  • 40
josefx
  • 15,506
  • 6
  • 38
  • 63
  • 4
    "Objects are passed by reference by default" - That's wrong. Everything is pass-by-value in Java. Where it gets confusing is that **references** (non-primitive variables) are also passed **by value**. Note that passing a reference by value is not the same as passing an object by reference. – Jesper Jan 17 '11 at 12:45
  • 1
    @Jesper it's not completely wrong, objects are always passed by reference in java. That the reference itself is passed by value is also true. – josefx Jan 17 '11 at 13:06
  • 1
    You cannot directly pass objects. Variables of non-primitive types are references - they are not the objects themselves, as in C++. Talking about "passing objects" is imprecise terminology when you're talking about Java. – Jesper Jan 17 '11 at 13:14
  • @Jesper could you define "pass" for me, it seems that my english skills aren't up to the task. – josefx Jan 17 '11 at 13:51
  • 1
    "pass" in this context means that you use the variable as an argument in a method call. But the point is not in the word "pass", but in the fact that variables in Java are references, and do not directly represent objects, as in C++. – Jesper Jan 17 '11 at 14:23
7

An ordinary Java parameter already is closer to a C++ reference than to C++ pass-by-value or pass-by-pointer. So, all your Java methods are already like this.

int and other primitives are special in Java, however; the above is true for object references.


Edit: More precisely, as stated @fatih, all Java invocations are pass-by-value. However, when you pass an object you are passing a reference by value. So, as a first approximation, the above statement is correct: An ordinary Java parameter is more similar to a C++ reference than to C++ pass-by-value or pass-by-pointer.

Joshua Fox
  • 18,704
  • 23
  • 87
  • 147
5

Required reading on understanding Java's Pass By Value semantics:

http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html http://javadude.com/articles/passbyvalue.htm http://javachannel.net/wiki/pmwiki.php/FAQ/PassingVariables (links to several other pages)

Completely remove the notion from your head that Java can have anything passed by reference. Let's look at an example, shall we?

public class App
{
    public static void main( String[] args )
    {
        Foo f1 = new Foo();
        doSomethingToFoo(f1);
        System.out.println(f1.bar); //Hey guess what, f1.bar is still 0 because JAVA IS PASS BY VALUE!!!
    }

    static void doSomethingToFoo(Foo f) {
        f = new Foo();
        f.bar = 99;
    }

    static class Foo {
        int bar = 0;
    }
}
whaley
  • 16,075
  • 10
  • 57
  • 68
  • 5
    What happen if you remove the line that read `f = new Foo()` ? My guess is that you'll get 99 printed, not 0. – xryl669 Mar 03 '17 at 11:19
0

The MutableInt class in Apache Commons will do what you want, although it's not pretty.

MutableInt

void sum(MutableInt mx)
{
    int x = mx.getValue();
    x = ...
    mx.setValue(x);
}

...

MutableInt mx = new MutableInt(5);
sum(mx);
int result = mx.getValue();

Additional classes are provided for other primitive types, and also for objects.

There is some overhead involved in creating an additional object simply to provide a reference, so the solution is not optimal, but in most cases you should be ok.

In general, it is always best to find a way to return a result from a method. Unfortunately, Java only allows one value to be returned in this way.

rghome
  • 8,529
  • 8
  • 43
  • 62