Dimath
Dimath

Reputation: 381

Assign a value to a return variable in Java

It is probably a basic question, but I am not sure what keywords to use to search it.

Is it possible to assign a value to a return variable in Java, something like that:

static int a[] = new int[2];

static int f(int i) {
    return a[i];
}

static void main() {
    f(1) = 0; // <-- this
}

In C/C++ I can return a pointer and assign a value to it later. Since Java works with references I would expect the code above to work. Am I missing some important Java concept here?

Upvotes: 2

Views: 3323

Answers (8)

xagyg
xagyg

Reputation: 9721

The OP's question is

Is it possible to assign a value to a return variable in Java

Very simple... (note I assign 10 to show proof since all values are 0 in an initialised int array)...

static int a[] = new int[2];

static int f(int[] p, int index, int val) {
    return p[index] = val;
}

static void main() {        
    // f(a, 1, 0); use 10 (below) so we can show proof
    f(a, 1, 10);
    // proof
    System.out.println(a[1]);
}

Another example ... silly, but works ...

static int a[] = new int[2];

static int[] f(int[] p) {
    return p;
}

static void main() {
    f(a)[1] = 10;
}

Yet another ...

static int a[] = new int[2];

static void f(int i, int val) {
    a[i] = val;
    return;
}

static void main() {
    f(1, 10);
}

Upvotes: 0

Daniel Earwicker
Daniel Earwicker

Reputation: 116674

You may be interested in how lambdas can be applied to this problem, though this only works in the Java 8 preview.

Suppose there was an interface defined like this in the standard libraries:

interface Block<T> {
    void accept(T v);
}

(There is a proposal to put that in java.util.functions, with only a little more complexity added...)

Now we can write your example like this:

// Declare an array
int[] a = new int[5];

// Capture an "assignment reference" to element 2 
Block<Integer> elem2 = v -> a[2] = v;

// Some time later, we want to store a new value in that element:
elem2.accept(360);

So your function would return Block<Integer>, on which you could later call accept to give it a value to store.

Upvotes: 0

Richard JP Le Guen
Richard JP Le Guen

Reputation: 28753

This will be a compilation error because the Assignment Operator requires that the left-hand-side be either an Expression Name, an Field Access Expression, or an Array Access Expression, whereas f(1) is a Method Invocation Expression.

Compilation errors aside, this isn't how Java works. In Java, everything is pass by value - especially so in this particular example since your return type is int.

static /*RETURN TYPE IS PRIMITIVE VALUE:*/ int f(int i) {
    return a[i];
}

If we add an intermediate variable it becomes clearer:

static /*RETURN TYPE IS PRIMITIVE VALUE:*/ int f(int i) {
    int ret = a[i]; // ret is an independent value from a[i]
                    // it and a[i] can be changed without affecting each other
    return return ret;
}

Upvotes: 0

bikeshedder
bikeshedder

Reputation: 7487

This is not possible (see the other comments) but you can create your own MutableInteger class which allows modifying its value:

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

static MutableInteger a[] = new MutableInteger[2];
static {
    for (int i=0; i<a.length; i++) {
        a[i] = new MutableInteger();
    }
}

static MutableInteger f(int i) {
    return a[i];
}

static void main() {
    f(1).value = 0; // <-- this
}

Upvotes: 0

user586399
user586399

Reputation:

Even if it is reference type, the method invokation is not a variable.

However, something like this would be OK:

static MyClass func() {
   return new MyClass();
}

public static void main(String[] args) {
   func().setAttr(null); // change attributes
}

Upvotes: 5

NPE
NPE

Reputation: 500475

One way is to turn your array into an array of MutableInts (or AtomicIntegers), and return a reference to the i-th element of that array:

static AtomicInteger a[] = new AtomicInteger[2];
static {
    for (int i = 0; i < a.length; ++i) {
        a[i] = new AtomicInteger(0);
    }
}

static AtomicInteger f(int i) {
    return a[i];
}

public static void main(String[] args) {
    f(1).set(0);
}

Upvotes: 0

C-Otto
C-Otto

Reputation: 5843

This will not work. Maybe it helps to understand what happens on "machine" level. Inside the method f the expression a[i] is evaluated to an int value. This int value is returned, without any connection to the array associated with that value. After returning from the method, you have the int value on the operand stack of the Java Virtual Machine (think of it as an intermediate value) and can do something with it. You can drop it (which happens if you write f(1); in a single line), you can assign it to a variable (int x = f(1)), and that's about it.

Upvotes: 0

Aasmund Eldhuset
Aasmund Eldhuset

Reputation: 37950

No. In Java, there are only primitive types (which behave mostly like they do in C++) and reference types. Reference types behave like a mixture between C++ pointers and C++ references - they are automatically dereferenced when you use ., but = always changes what the reference points to, not the value of the object being referenced.

Upvotes: 0

Related Questions