2

I try to set the values of a 2D boolean array with 2 loops like this:

 boolean[][] frame = new boolean[10][4];
    for (boolean[] column : frame)
        for (boolean b : column)
            b = true;

But that doesnt seem to work, all booleans remain false, why?

djechlin
  • 59,258
  • 35
  • 162
  • 290
Big_Chair
  • 2,781
  • 3
  • 31
  • 58
  • 2
    `b` is a local variable in the loop. Changing it's value does not affect the array content. – jlordo Mar 01 '13 at 15:56

2 Answers2

6

You cannot assign new values to objects in an array, because the original object will not be changed. Following code will do the trick.

boolean[][] frame = new boolean[10][4];
for (boolean[] column : frame)
    for (int i = 0; i < column.length; i++)
        column[i] = true;

A bit more explanation:

The array contains elements which point to booleans. When you assign the value of one of the elements of the array to a variable called b (for (boolean b : column)), the variable b points to the same object the element in the array points to. Next, you point the variable b to true. Now, b will be true. However, the element in the array still points to the same object.

I hope this is clear now. An image would make it more understandable...

Fortega
  • 19,463
  • 14
  • 75
  • 113
  • Damn, I should've guessed that b can only be a copy and not the object itself, thank you for explaining – Big_Chair Mar 01 '13 at 16:41
5

Because you're reassigning b which is a copy of column[i], not column[i] itself. Primitives in Java are (or at least "are best thought of") as passed/copied by value, not by reference.

More precisely Java is pass-by-value-of-reference which throws off the amateur "pass by value"/"pass by reference" dichotomists. For primitives I don't know if "strictly speaking" they are by value but they are immutable so there is no semantic distinction in this case. e.g.

public class Foo {
      public int x;

      public static void main(String args[]) {
            Foo a = new Foo();
            Foo b = a;
            Foo c = new Foo();
            a.x = 1; //b.x is now 1
            b.x = 2; //a.x is now 2
            a = c;
            a.x = 3; //b.x is still 2 because a's reference changed
      }
}

Understand that code and you will understand the problem with yours.

djechlin
  • 59,258
  • 35
  • 162
  • 290
  • Even if that were (SomeObject b : column) it wouldn't work. The problem isn't that it's a primitive, it's that changing what the variable points to doesn't change what the array points to. – Herms Mar 01 '13 at 15:57
  • is "b.x = 2; //a.x is now 2" really true? I thought "a.x is now 2" would only apply, if you would additionally set "a=b" – Big_Chair Mar 01 '13 at 16:46
  • @Big_Chair it is correct. References do not actually point to each other. Whenever you read `left=right` this actually means `left = right's object`. So at `b = a` means `b = a's Foo`, so when `b.x = 2` is called it means `(a's Foo).x = 2`. – djechlin Mar 01 '13 at 17:09