views:

2766

answers:

11

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 an error like '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. Now my question is, what does it mean to put that keyword before the declaration? What exactly will it do/restrict in terms of what can be done to that object?

+28  A: 

static members belong to the class instead of a specific instance.

It means that only one instance of a static field exists 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 (how would you know which instance Hello class you want to refer to?). static members can only refer to static members. Instance members can, of course access static members.

Side note: Of course, static members can access instance members through an object reference.

Mehrdad Afshari
True, but not complete. A static field will have one value per classloader. Not a concern for most developers, granted.
Apocalisp
@Apocalisp: I didn't want to go through implementation in different programming languages. My answer was mostly about the concept of static stuff. For example in C#, static fields have one value per AppDomain. I thought it might make things a bit complicated. Thanks for the point.
Mehrdad Afshari
In .NET, you can also modify this behavior using the [ThreadStatic] attribute - which makes the static local to particular threads.
TheSoftwareJedi
+1 TheSoftwareJedi, nice point. And of course, static fields can have unique values on different machines! These factors depend on the programming languages, but the concept of static members is roughly the same (at least, in Java, C#, C++, VB, ...)
Mehrdad Afshari
A: 

It means you don't have to have an instance of the class to use the method. So in your example, you could call:

Hello.main(new String[]())

directly, instead of:

Hello h = new Hello();
h.main(new String[]());

Edit

From inside a static method (one belonging only to the class) you cannot access any members which are not static, since their values depend on your instantiation of the class. So Clock, 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.

Elie
He wasn't asking about the static in front of "main", he was asking about "static Clock"
Paul Tomblin
There is no static in front of Clock.
Elie
Try reading the whole question, not the first two lines.
Paul Tomblin
Did, and updated the answer.
Elie
+13  A: 

It means that there is only one instance of "clock" in Hello, not one per instance of Hello. So if you were to do a "new Hello" anywhere in your code, in the first instance (without the "static"), it would make a new clock, but in the second instance, it would still use the original "clock".

Unless you needed "clock" somewhere outside of main, this would work just as well:

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}
Paul Tomblin
This is the more usual way of doing it. The `main()` routine should be self-contained.
Jason S
In the second instance it would create a new instance of Clock each time the main method is called, right?
Click Upvote
In the second instance, clock static, it would only create it once. In my example, where clock is within the main, then yes, it would create it new every time main is called. But normally main is only called once on program start, and when it exits, everything is free-ed.
Paul Tomblin
+1  A: 

Static makes the clock member a class member instead of an instance member. Without the static keyword you would need to create an instance of the Hello class (which has a clock member variable) - e.g.

Hello hello = new Hello();
hello.clock.sayTime();
Stephen Doyle
+2  A: 

static methods don't use any instance variables of the class they are defined in. A very good explanation of the difference can be found on this page

Marc Novakowski
+2  A: 

A field can be assigned to either the class or an instance of a class. By default fields are instance variables. By using static the field becomes a class variable, thus there is one and only one clock. If you make a changes in one place, it's visible everywhere. Instance varables are changed independently of one another.

sblundy
+5  A: 

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.

Julien Chastang
This was mentioned by Apocalisp in the comments on Merhdad's answer.
Zach Langley
Good point. Many people don't know this, but once you start messing with classloaders, it becomes very important.
sleske
A: 

Can also think of static members not having a "this" pointer. They are shared among all instances.

kal
+2  A: 

Once again remember that there is one instance of a static per class per CLASSLOADER.

Javamann
A: 

The static keyword in Java means that the variable or function is shared between all instances of that class as it belongs to the type, not the actual objects themselves.

So if you have a variable: private static int i = 0; and you increment it (i++) in one instance, the change will be reflected in all instances. i will now be 1 in all instances.

Static methods can be used without instantiating an object.

geowa4
"Shared between all instances" gives the wrong impression, IMO - it suggests that you *do* need to have an instance of the object.
Jon Skeet
(Whereas really there don't need to be *any* instances, because the static field etc belongs to the *type*.)
Jon Skeet
will edit, thanks
geowa4
+6  A: 

The static keyword means that something (a field, method or inner class) is related to the type rather than any particular instance of the type. So for example, one calls Math.sin(...) without any instance of the Math class, and indeed you can't create an instance of the Math class.

For more information, see the relevant bit of Sun's Java Tutorial.


Sidenote

Java unfortunately allows you to access static members as if they were instance members, e.g.

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

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:

// Clearer
Thread.sleep(5000);
Jon Skeet
+1 for mentioning that it is bad, that calling from an instance-variable is allowed.
Mnementh