“static”关键字在类中的作用是什么?

具体来说,我正在尝试这个代码:

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

但它给出了错误

无法访问静态方法 main 中的非静态字段

所以我把声明改成了:clock

static Clock clock = new Clock();

它奏效了。在声明之前放置该关键字是什么意思?它究竟会做什么和/或限制对该对象可以做些什么?


答案 1

static成员属于类而不是特定实例。

这意味着只有一个静态字段的实例存在[1],即使您创建了该类的一百万个实例,或者您没有创建任何实例。它将由所有实例共享。

由于方法也不属于特定实例,因此它们不能引用实例成员。在给出的示例中,不知道它应该引用类的哪个实例(以及该类的哪个实例)。 成员只能引用成员。实例成员当然可以访问成员。staticmainHelloClockstaticstaticstatic

附注:当然,成员可以通过对象引用访问实例成员。static

例:

public class Example {
    private static boolean staticField;
    private boolean instanceField;
    public static void main(String[] args) {
        // a static method can access static fields
        staticField = true;

        // a static method can access instance fields through an object reference
        Example instance = new Example();
        instance.instanceField = true;
    }

[1]:根据运行时特征,它可以是每个类加载器或AppDomain或线程一个,但这不是重点。


答案 2

这意味着 Hello 中只有一个“时钟”实例,而不是 “Hello” 类的每个单独实例都有一个,或者更多,这意味着在 “Hello” 类的所有实例中将有一个通常共享的“时钟”引用。

因此,如果您在代码中的任意位置执行“new Hello”:A-在第一个场景中(在更改之前,不使用“static”),它将在每次调用“new Hello”时创建一个新时钟,但是在第二个场景中(在更改之后,使用“static”)中,每个“new Hello”实例仍将共享并使用首次创建的初始和相同的“时钟”引用。

除非你在 main 之外的某个地方需要“时钟”,否则这同样有效:

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}