posted 20 years ago
I think the problem you're having is that you're trying to set an instance variable of a particular object without knowing what instance you're dealing with. (That's what the error message you're getting means.) You have to understand what it means for something to be static, and then I think you'll see what's going on here.
Let's say you write a Dog class. For the sake of simplicity, let's say a dog only has a name in your application, so you'd make name an instance variable and provide a name setter and a name getter. Now let's say you want to make sure you keep count of the total number of dogs ever created in your application (for this app, you don't care how many are still "alive"--have objects roaming around the system--you only want to track how many have been new'd up). How would you do this?
Well, you might say, just include a numDogs variable and increment it whenever a new Dog instance gets constructed. Ok...
Do you see the problem with the above code?
The problem is, if you create two dogs, rover and bowser, they'll both be carrying around a numDogs variable that's equal to 1. This doesn't tell you how many total dogs have been created. Furthermore, when those two instances are gc'd, the numDogs variables die with them.
Instead of attaching that numDogs variable to a Dog instance--that is, a specific dog, like rover or bowser--what if you could attach it to the Dog class itself? That would mean it wasn't owned by any one dog, it would exist independently of any one dog. You can...just make it static:
Now, every time you write a statement like Dog rover = new Dog(), the numDogs variable that's stored up at the class level gets incremented. If you think of a class as a rubber stamp, and an instance as the ink left behind by that stamp, you'll quickly see the difference. You stamp out two dog imprints, rover and bowser, and each ink imprint has data associated with it that can change independently of the other. Rover's name is set to "rover" and bowser's to "bowser"--that data is unique to each instance.
Declaring something static, though, means you're not talking about the imprints left behind by the stamp, that's data associated with the stamp itself. In the code example above, numDogs is now attached to the stamp, so every time you plunk out a new dog instance, that counter on the stamp goes up by one.
Also note the way I've referred to the static data. Normally, when you access a data member, you'd say instance.data. But note that I've written Dog.numDogs. Dog is the *class*, not an instance like rover or bowser. Java confusingly will let you refer to static data using an instance reference (which I think I know why, but still don't agree with), but to keep things simple and clear to other developers I never do that. Besides, what if there are no instances available?
That's right...think about it. Even before the stamp has stamped out a single instance, you should be able to get access to that numDogs variable and see that it's zero, right? Well, you can...since you don't require an instance to get at it, you can just say: Dog.numDogs.
Static methods are similar--they are behaviors attached to the class, not to any specific instance of that class. Normally, you write a method and it has access to all of the instance variables. For example, the getNumDogs() method in the second example (note that I snuck a "static" in there too) seems like I should be able to add code that prints out the name of the dog, right? Wrong...think about it. If I said, S.o.println( name ), how would the static method know which instance I'm talking about, bowser or rover? It doesn't know--it's attached to the stamp, not a specific inking. So, static methods require that an instance be passed into them if you want them to operate on those instances. If you try to reference a non-static variable or method from a "static context"--inside a static method--you'll get the error message you got.
Make sense?
sev