Reputation: 381
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
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
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
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
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
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
Reputation: 500475
One way is to turn your array into an array of MutableInt
s (or AtomicInteger
s), 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
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
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