Why is Java reference is not working like expected in this Program
I was working in a problem and I found that Java references are not working as I expect it to. Ofcourse, I am the culprit :), can someone please me why the following happens. Let me first post the code here.
package misc.matrix;
public class ReferenceTester {
public static void main(String args[]){
Boolean[][] input = {
{true ,false ,true ,true ,false },
{false ,true ,true ,true ,true },
{true ,true ,true ,true ,true },
{true ,true ,true ,true ,true },
{true ,false ,true ,true ,true }
};
print(input);
for(Boolean[] eachRow:input){
for(Boolean eachVal:eachRow){
eachVal = Boolean.TRUE;
}
}
print(input);
/*Expected output
true true true true true
true true true true true
true true true true true
true true true true true
true true true true true
*/
}
/**
* Simply prints the array
*/
private static void print(Boolean[][] input) {
for(Boolean[] outArray:input){
for(Boolean iVal:outArray){
System.out.print(iVal?iVal+" ":iVal+" ");
}
System.out.println();
}
}
}
If you take a look at the above program, all I am trying to do is to change all the values in the Array to true and print it. But its simply prints the input again. Can someone please tell me why is this. Initially I had used the primitive boolea开发者_C百科n in the program, but since I dont want to create copies, I used the wrapper Boolean Class which is a Java OBJECT as opposed to primitives. (Isnt eachVal a JAVA OBJECT!?!?!?!?) Why is this happening in Java. Why did it not print all the values to be true?
Please advise.
You cannot modify the source object within a foreach loop. Your loop will have to be a standard for loop like this:
for(int i = 0; i < input.length; i++){
for(int j = 0; j < input[i].length; j++){
input[i][j] = true;
}
}
Edit: To be more precise, eachVal
in your loop is a pointer, not a reference; hence setting it to point to a different value does not change the original.
The exact form that the foreach loop uses behind the scenes is given here, if you wish to confirm this independently.
Your problem is with the loop to change the value of the array:
for(Boolean[] eachRow:input){
for(Boolean eachVal:eachRow){
eachVal = Boolean.TRUE;
}
}
On each iteration, the variable eachVal
holds a reference to the content of the cell of the array, just as you expect. But the problem is that, since Boolean
is an immutable type---that is, you can't change the value of a Boolean
object after it's been created---your assignment doesn't work. In fact, what you're actually doing is changing the object that the eachVal
reference points to. That is, since eachVal
is an independent variable from input
and eachRow
, you're simply reassigning this variable without ever touching the contents of the array.
Let me know if you want me to expand upon or clarify any particular point.
@mmyers had the answer, you asked for more detail but I couldn't fit it in a comment:
So you have an array of references to booleans (it's ALWAYS references) and in your for each loop you create a reference that points to the same boolean as a member of that array.
Each iteration the reference is updated to point to what the next pointer in the array points to.
When you use equals, you are simply re-assigning the reference to point to something else.
If you wanted to update the object inside your array, it would have to be mutable (Boolean is not) and you would have to use a mutator instead of equals.
What you are attempting is analogous to the following:
int[] arr = { 1, 2, 3 };
for (int i : arr) {
i = 0;
}
This does NOT set all values in the array to 0. Java passes everything by value.
精彩评论