What is “static”?

2020-01-29 07:25发布

问题:

I'm beginning to program in Java.

public static void main(String[]args)

A book said that I should use static in this case, but doesn't clearly say why I should or what it means.

Could you clarify this?

回答1:

The concept of static has to do with whether something is part of a class or an object (instance).

In the case of the main method which is declared as static, it says that the main method is an class method -- a method that is part of a class, not part of an object. This means that another class could call a class method of another class, by referring to the ClassName.method. For example, invoking the run method of MyClass would be accomplished by:

MyClass.main(new String[]{"parameter1", "parameter2"});

On the other hand, a method or field without the static modifier means that it is part of an object (or also called "instance") and not a part of a class. It is referred to by the name of the specific object to which the method or field belongs to, rather than the class name:

MyClass c1 = new MyClass();
c1.getInfo()     // "getInfo" is an instance method of the object "c1"

As each instance could have different values, the values of a method or field with the same name in different objects don't necessarily have to be the same:

MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();

c1.value     // The field "value" for "c1" contains 10.
c2.value     // The field "value" for "c2" contains 12.
             // Because "c1" and "c2" are different instances, and 
             // "value" is an instance field, they can contain different
             // values.

Combining the two concepts of instance and class variables. Let's say we declare a new class which contains both instance and class variables and methods:

class AnotherClass {
    private int instanceVariable;
    private static int classVariable = 42;

    public int getInstanceVariable() {
        return instanceVariable;
    }

    public static int getClassVariable() {
        return classVariable;
    }

    public AnotherClass(int i) {
        instanceVariable = i;
    }
}

The above class has an instance variable instanceVariable, and a class variable classVariable which is declared with a static modifier. Similarly, there is a instance and class method to retrieve the values.

The constructor for the instance takes a value to assign to the instance variable as the argument. The class variable is initialized to be 42 and never changed.

Let's actually use the above class and see what happens:

AnotherClass ac1 = new AnotherClass(10);

ac1.getInstanceVariable();             // Returns "10"
AnotherClass.getClassVariable();       // Returns "42"

Notice the different ways the class and instance methods are called. The way they refer to the class by the name AnotherClass, or the instance by the name ac1. Let's go further and see the behavioral differences of the methods:

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
AnotherClass.getClassVariable();       // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
AnotherClass.getClassVariable();       // Returns "42"

As can be seen, an instance variable is one that is held by an object (or "instance"), therefore unique to that particular instance, which in this example is the objects referred to by ac1 and ac2.

A class variable on the other hand is only unique to that entire class. To get this point across even better, let's add a new method to the AnotherClass:

public int getClassVariableFromInstance() {
    return classVariable;
}

Then, run the following:

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
ac1.getClassVariableFromInstance();    // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
ac2.getClassVariableFromInstance();    // Returns "42"

Although getClassVariableFromInstance is an instance method, as can be seen by being invoked by referring to the instances ac1 and ac2, they both return the same value, 42. This is because in both instance methods, they refer to the class method classVariable which is unique to the class, not to the instance -- there is only a single copy of classVariable for the class AnotherClass.

I hope that some what clarifies what the static modifier is used for.

The Java Tutorials from Sun has a section called Understanding Instance and Class Members, which also goes into the two types of variables and methods.



回答2:

Please see a nice description on Wikipedia

For example, notice how in the Math class, you can say things like

Math.Abs(x);

without having to say

Math m = new Math();

These are static methods since you don't need an instance. Instance methods are those methods that require you to have an instance of a class.

Employee e = new Employee();
e.Terminate();


回答3:

A static method is one that applies to the class a whole, not any particular member. .goExtinct() would be a method of the Duck population as a whole, not any particular duck. main is public and static because is has to always be available, and its not part of any particular class.



回答4:

Usually, you have to have an object, an instance of a class, in order to call methods on it, for at least two reasons:

  1. It depends on the object which class implements the method that is being called. For example if you have an instance of a subclass, the method in the subclass will be called instead, even though the code that calls the method is the same.
  2. Objects usually have internal state (fields), that methods can refer to. This does not work if there is no object instance.

You create object instances by calling the class' constructor:

MyObject a = new MyObject();

Static methods are methods that are not attached to object instances. They can be called by just naming the class. As a result of this they

  1. cannot be dynamically dispatched to subclasses (which is why you get a warning when you try to call it on object instances, that is just confusing syntax)
  2. they cannot refer to instance state (non-static fields and other non-static methods).

Many people consider static methods a bad design pattern, and advise to not use them (except for public static void main) Look up the singleton instance pattern for an alternative.



回答5:

In this particular case the main method must be static, because of the way the JVM will start loading classes and creating objects. When you start a Java program the JVM will look for the definition of the class that was passed to it and load it. So java MyClass will result in loading the definition of the MyClass class.

By definition a Java program will start executing in the main() method of the class that was passed to the JVM as the class to load initially. At this point in time no instance (object) of type MyClass has been created, so the main method has to be static to allow the start of the execution of your program.

If you want to see which classes are being loaded during the execution of a Java program you can use the -verbose:class command line option.



回答6:

In any object oriented programming language like Java or C++ you create classes which at the very basic level are like BluePrints of a building. You can look at a blueprint and determine how various components are connected but you cannot actually live in it. It's the same with classes and object. Classes are blueprint and you create an instance of a class which is called an Object. For the same blueprint you can have multiple buildings , same way for one class you can have multiple objects. An Object is an instance of a class. Each method in a class can be called on an Object or an instance of a class, whereas for calling static methods you actually don't need an instance, you can directly call ClassName.method() without actually creating an instance of a class.



回答7:

There will be times when you will want to define a class member that will be used independently of any object of that class. Normally a class member must be accessed only in conjunction with an object of its class. However, it is possible to create a member that can be used by itself, without reference to a specific instance. To create such a member, precede its declaration with the keyword static. When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object. You can declare both methods and variables to be static. The most common example of a static member is main( ). main( ) is declared as static because it must be called before any objects exist. The two types of static members are static fields and static methods:

Static field:

A field that’s declared with the static keyword, like this:

private static int ballCount:

The position of the static keyword is interchangeable with the positions of the visibility keywords (private and public, as well as protected). As a result, the following statement works, too:

static private int ballCount;

As a convention, most programmers tend to put the visibility keyword first.

The value of a static field is the same across all instances of the class. In other words, if a class has a static field named CompanyName, all objects created from the class will have the same value for CompanyName.

Static fields are created and initialized when the class is first loaded. That happens when a static member of the class is referred to or when an instance of the class is created, whichever comes first.

Static method: 

A method declared with the static keyword. Like static fields, static methods are associated with the class itself, not with any particular object created from the class. As a result, you don’t have to create an object from a class before you can use static methods defined by the class.

The best-known static method is main, which is called by the Java runtime to start an application. The main method must be static, which means that applications run in a static context by default.

One of the basic rules of working with static methods is that you can’t access a nonstatic method or field from a static method because the static method doesn’t have an instance of the class to use to reference instance methods or fields.



标签: java static