4

I've been pulling my hair out with this all day. Probably a newb error of some sort, but I can't get my head around it.

It started out more complicated, but I've simplified it to:

public class Main {

    static ArrayList<Selection>[] a = new ArrayList[2];

    public static void main(String[] args) {

        // Initialise the Selection ArrayList

        for (int i=0; i < a.length; i++) {
            a[i] = new ArrayList<Selection>();
        }

        callTest();

    }

    public static void callTest () {

        a[0].add(new Selection(true));
        a[1].add(new Selection(false));

        System.out.println(a[0].get(0).getTF());
        System.out.println(a[1].get(0).getTF());
    }
}

class Selection {

    private static boolean trueFalse;

    public Selection (boolean iTF) {
        trueFalse = iTF;
    }

    public boolean getTF () {
        return trueFalse;
    }
}

Running the program will return:

false
false

instead of the expected (at least to me):

true
false

Can someone please shed some light on this? It appears that whenever the value held in a Selection object is altered, ALL the Selection objects are altered, even though they have a different object reference. Have I done something silly?

6
  • Well, I see already static ArrayList<Selection>[] a = new ArrayList[2]; should be static ArrayList<Selection>[] a = new ArrayList<Selection>[2]; Commented Aug 3, 2011 at 18:47
  • That comes up as invalid as far as my IDE is concerned, but I did try it that way. Commented Aug 3, 2011 at 19:46
  • Well, that's strange. I'm a bit out of the Java loop though, so high potential for my fail. Commented Aug 3, 2011 at 19:47
  • Upon double-checking, even though the IDE complains if it IS there, the compiler itself complains if it ISN'T there. Commented Aug 5, 2011 at 12:56
  • Well, that's even more strange, no idea why that would happen. Commented Aug 5, 2011 at 13:26

5 Answers 5

17

It's because truefalse is static, part of the class and not part of the object. So there's only one truefalse value for all of the Selection objects, and it just gets altered every time a constructor is called. You'll want to remove the static modifier, then all should work as planned!

To avoid problems like this in future, it's best at least while you're starting out to not declare things as static like this - keep to objects where you possibly can, even when you know you're only creating one! This gets you in a nice OO mindset and reduces these types of problems. Of course, there are places where you need to use it and it's the right thing to do, but you'll learn that as you go along.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks to all that answered this, makes sense after it's been pointed out to me!
@shakeshuck No problem at all, glad to help!
8

This is because in Selection you declare trueFalse as a static variable. Simply change it to :

class Selection {

    //one per Selection, versus a global variable
    private boolean trueFalse;

    public Selection (boolean iTF) {
        trueFalse = iTF;
    }

}

Comments

4

Change

private static boolean trueFalse;

to

private boolean trueFalse;

That should fix it. Basically since trueFalse is static, its shared by each instance of the Selection class.

Comments

4

In class Selection you've declared trueFalse as static. That means that it's part of the class, not part of the instances, so it's shared by all the instances.

Comments

4

From The Java Tutorials:

  • Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated.

This is most definitely a "newb" error.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.