To be specific, I was trying this code:
package hello;
public class Hello {
Clock clock = new Clock();
public static void main(String args[]) {
clock.sayTime();
}
}
But it gave the error
Cannot access non-static field in static method main
So I changed the declaration of clock
to this:
static Clock clock = new Clock();
And it worked. What does it mean to put that keyword before the declaration? What exactly will it do and/or restrict in terms of what can be done to that object?
Basic usage of static members...
That's how you can have values shared in all class members without sending class instance Hello to other class. And whit static you don't need to create class instance.
You can just call static values or methods by class name:
The
static
keyword means that something (a field, method or nested class) is related to the type rather than any particular instance of the type. So for example, one callsMath.sin(...)
without any instance of theMath
class, and indeed you can't create an instance of theMath
class.For more information, see the relevant bit of Oracle's Java Tutorial.
Sidenote
Java unfortunately allows you to access static members as if they were instance members, e.g.
That makes it look as if
sleep
is an instance method, but it's actually a static method - it always makes the current thread sleep. It's better practice to make this clear in the calling code:static
members belong to the class instead of a specific instance.It means that only one instance of a
static
field exists[1] even if you create a million instances of the class or you don't create any. It will be shared by all instances.Since
static
methods also do not belong to a specific instance, they can't refer to instance members. In the example given,main
does not know which instance of theHello
class (and therefore which instance of theClock
class) it should refer to.static
members can only refer tostatic
members. Instance members can, of course accessstatic
members.Side note: Of course,
static
members can access instance members through an object reference.Example:
[1]: Depending on the runtime characteristics, it can be one per ClassLoader or AppDomain or thread, but that is beside the point.
This discussion has so far ignored classloader considerations. Strictly speaking, Java static fields are shared between all instances of a class for a given classloader.
It means that there is only one instance of "clock" in Hello, not one per each separate instance of the "Hello" class, or more-so, it means that there will be one commonly shared "clock" reference among all instances of the "Hello" class.
So if you were to do a "new Hello" anywhere in your code: A- in the first scenario (before the change, without using "static"), it would make a new clock every time a "new Hello" is called, but B- in the second scenario (after the change, using "static"), every "new Hello" instance would still share and use the initial and same "clock" reference first created.
Unless you needed "clock" somewhere outside of main, this would work just as well:
Static means that you don't have to create an instance of the class to use the methods or variables associated with the class. In your example, you could call:
directly, instead of:
From inside a static method (which belongs to a class) you cannot access any members which are not static, since their values depend on your instantiation of the class. A non-static Clock object, which is an instance member, would have a different value/reference for each instance of your Hello class, and therefore you could not access it from the static portion of the class.