具体来说,我正在尝试以下代码:

package hello;

public class Hello {

    Clock clock = new Clock();

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

但是它给出了错误

不能访问静态方法主中的非静态字段

所以我把时钟的声明改为这样:

static Clock clock = new Clock();

这招奏效了。将该关键字放在声明之前意味着什么?它究竟会做什么和/或限制可以对该对象做什么?


当前回答

我喜欢在“助手”类中使用静态方法(如果可能的话)。

调用类不需要创建helper类的另一个成员(实例)变量。您只需调用helper类的方法。helper类也得到了改进,因为不再需要构造函数,也不需要成员(实例)变量。

或许还有其他优势。

其他回答

Java中的静态:

Static是一个非访问修饰符。 static关键字属于该类的类的实例。 可用于将变量或方法附加到类。

Static关键字可以用于:

方法

变量

嵌套在另一个类中的类

初始化块

不能与:

类(非嵌套)

构造函数

接口

局部内部类(区别于嵌套类)

内部类方法

实例变量

局部变量

例子:

想象一下下面的例子,它有一个名为count的实例变量,它在构造函数中递增:

package pkg;

class StaticExample {
    int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

输出:

1 1 1

由于实例变量在对象创建时获得内存,因此每个对象都会有实例变量的副本,如果该副本增加,则不会反射到其他对象。

现在,如果我们将实例变量计数改为静态变量,那么程序将产生不同的输出:

package pkg;

class StaticExample {
    static int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

输出:

1, 2, 3

在这种情况下,静态变量将只获得一次内存,如果任何对象改变了静态变量的值,它将保留其值。

静态与Final:

The global variable which is declared as final and static remains unchanged for the whole execution. Because, Static members are stored in the class memory and they are loaded only once in the whole execution. They are common to all objects of the class. If you declare static variables as final, any of the objects can’t change their value as it is final. Therefore, variables declared as final and static are sometimes referred to as Constants. All fields of interfaces are referred as constants, because they are final and static by default.

图片来源:最终静态

Static使时钟成员成为类成员而不是实例成员。如果没有static关键字,你需要创建一个Hello类的实例(它有一个时钟成员变量)。

Hello hello = new Hello();
hello.clock.sayTime();

静态意味着您不必创建类的实例来使用与类关联的方法或变量。在你的例子中,你可以调用:

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class

直接,而不是:

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

在静态方法(属于类)内部,您不能访问任何非静态的成员,因为它们的值取决于类的实例化。非静态Clock对象是实例成员,对于Hello类的每个实例都有不同的值/引用,因此不能从类的静态部分访问它。

静态成员属于类,而不是特定的实例。

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

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

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

例子:

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]:根据运行时特征,它可以是每个ClassLoader或AppDomain或线程一个,但这不是重点。

Main()是一个静态方法,它有两个基本限制:

静态方法不能使用非静态数据成员,也不能直接调用非静态方法。 This()和super()不能在静态上下文中使用。 A类{ Int a = 40;/ /非静态 public static void main(String args[]) { System.out.println(一个); } }

输出:编译时错误