views:

314

answers:

8

I've been running into this problem many times and I never bothered to learn why its happening and learn what "static" actually means. I just applied the change that Eclipse suggested and moved on.

public class Member {

 // Global Variables
 int iNumVertices;
 int iNumEdges;

 public static void main(String[] args) {

  // do stuff

  iNumVertices = 0; // Cannot make a static reference to the non-static field iNumVertices

  // do more stuff

 } // main end 
}

So eclipse tells me to do static int iNumVertices; and I'm not sure why. So what exactly is "static", how is it used, what is the purpose of using "static", and why is it giving me this problem?

Thanks.

+1  A: 

Static variables are class variables. There will be a single copy of that variable avaiable to all instances of the class and they will share that variable. Static members can also be used without referencing a specific instance of the class.

More here:

http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html

FrustratedWithFormsDesigner
A: 

Static variables do not need to have the class be instantiated in order to be accessed, so if you are trying to access a non-static variable form a static context you are risking trying to access something that has not been initialized/instantiated.

dave
A: 

static variables are common to all instances of a Class.

Note: As said earlier these are class variables i.e. shared by all instances.

These can also be called as class level variables. Generally you define Constants(You will also need final keyword for defining constants) and Global variables as static.

For more information refer: http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html

http://www.roseindia.net/java/beginners/staticvariable.shtml

YoK
A: 

Every class variable (a variable declared within the class body and outside the method bodies) used in a static method needs to be declared static too.

Static class variables and methods can be accessed outside that class without the need for an instance of that class.

Molske
+6  A: 

Here's your example:

public class Member {

    // Global Variables
    int iNumVertices;
    int iNumEdges;

    public static void main(String[] args) {

        // do stuff

        iNumVertices = 0; // Cannot make a static reference to the non-static field iNumVertices

    }
}

The method main is a static method associated with the class. It is not associated with an instance of Member, so it cannot access variables that are associated with an instance of Member. The solution to this is not to make those fields static. Instead, you need to create an instance of Member using the new keyword.

Here's a modified version:

public class Member {
    // Fields
    private int iNumVertices;
    private int iNumEdges;

    public Member(){
        // init the class
    }

    public static void main(String[] args) {
        Member member = new Member();
        member.iNumVertices = 0;
        // do more stuff
    }
}

Finding yourself creating global statics is an indication to you that you should think carefully about how you're designing something. It's not always wrong, but it should tell you to think about what you're doing.

Jonathon
ohhh... I see. That makes a lot of sense. Why did you decide to make the 2 global variables private? Is it because they belong to the Member class and should only be accessed by Member objects?
Hristo
It is a best practice to make everything private that does not need to be accessed from outside, even in a small test project with only one class.
f1sh
@Hristo It's my belief that in general, every instance variable (also called fields, properties, and some other names) should be private. You want to expose as little of the internal workings of your class as possible. This helps you make your class more predictable because you won't have someone else modify the state of your class. 6 months down the road when you're fixing a bug in your code, you won't have to worry about 5 other files changing your variables if you keep them private.
Jonathon
@Jonathon... Thanks for response. That makes sense and it seems like its good practice to keep them private. Luckily, this isn't a long term project... its a short solution to a puzzle I'm working on, so it won't be going on a huge scale. But I'll keep this in mind for future projects :)
Hristo
+1  A: 

Static methods can access only static variables. There are two kinds of variables in class. one is static variables(also class variables) and other is instance variable. Only one copy of Static variable exists in memory but instance variables will be instantiated for each object. So for static variables all objects access the same variable and any change made by one object will be reflected to other objects. The question here is why is that methods have to be static to access static variables. When you make a method static, you can access the method without instantiating objects of that class. So if this method is able to access instance variables then for which object's variables should it make change to? The other way is possible ie non static methods can access static variables.

So if I want a variable to be specific to each object... if I want each Member to be independent of another Member (for example if they are different ages), then I shouldn't be using static right?
Hristo
@Hristo Correct. The term "instance" refers to a unique, individual realization of the class. The class describes how each instance should be structured. Statics sidestep that and aren't really part of the individual instances. They can't be unique to an instance -- there's only one copy of a static, not one associated with each instance.
Jonathon
Thanks for the explanation. That makes sense.
Hristo
+1  A: 

static variables are those that are shared across all objects of a class. Here in your example for every object of Member you create , you will get objects that have it's own iNumVertices values. When you use static with a variable, there is only one variable shared across every object of Member. static methods work the same way - they are shared across all objects.

Since static variables/methods are common to all objects, one need not make an object of the class to access these variables/methods.

Non-static variables like iNumVertices belong to an object of a class. They cannot be accessed without creating an object. So when you access a non-static variable from a static context (here main method), then java wouldn't know which object's iNumVertices you are trying to accesss. Hence the error.

Either make iNumVertices static, or refer to it by creating an object of Member

Member m = new Member();
m.iNumVertices = 0;
Ara
So if I want a variable to be specific to each object... if I want each Member to be independent of another Member (for example if they are different ages), then I shouldn't be using static right?
Hristo
Exactly! That is exact purpose of member variables. You must not, however, confuse it with scope of a variable - public, private etc.
Ara
wait... I thought scope referred to the time range in which a variable lives. Are you saying that public, private, etc... also define the scope?
Hristo
public, private deals with inheritance and where all a variable/method is visible. static deals exclusively with sharing of variables within objects of a class. Scope is word used in both cases, but in completely different meanings.
Ara
interesting... I haven't encountered this before. I have always dealt with scope referring to the lifetime of a variable/object/etc... Thanks for your explanation.
Hristo
+3  A: 
learn what "static" actually means

What static actually means that Class variable will be same for all instance of that particular class, however if you want to avoid using static variables(which is a good idea, since static variables are being kept in memory) you can pass variable value trough constructor thereby avoiding usage of static modifier, and achieve the same effect(that is if you pass the same value upon class instantiation).

Here is code example :

public class Car{

    private int speed;

    public Car(int speed){
        this.speed = speed;
    }

}

So you can do this when creating new instance :

Car car = new Car(100);

and every time you create Car instance it will have speed 100, thus avoiding static declaration private static int speed = 100;

Gandalf StormCrow
ahh that's interesting... slightly different solution from the other answers. mind posting some code to demonstrate?
Hristo
@Hristo I added some code
Gandalf StormCrow
Thanks for the code.
Hristo
@Hristo if you want your example to work, you need to create function which sets the value of iNumVertices to 0(so called setter function). Then inside main you should instantiate your class `Member member = new Member();`, then call setter function to change the value of your class field, `member.setINumVertices(0);`
Gandalf StormCrow
@Gandalf... ahh right. That makes total sense. Thanks!
Hristo