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

package hello;

public class Hello {

    Clock clock = new Clock();

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

但是它给出了错误

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

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

static Clock clock = new Clock();

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


当前回答

static关键字意味着某些东西(字段、方法或嵌套类)与类型相关,而不是与类型的任何特定实例相关。例如,在没有Math类实例的情况下调用Math.sin(…),实际上您无法创建Math类的实例。

有关更多信息,请参阅Oracle的Java教程的相关部分。


旁注

不幸的是,Java允许你像访问实例成员一样访问静态成员。

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

这使它看起来好像sleep是一个实例方法,但实际上它是一个静态方法——它总是使当前线程休眠。更好的做法是在调用代码中清楚地说明这一点:

// Clearer
Thread.sleep(5000);

其他回答

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.

图片来源:最终静态

静态成员的基本用法…

public class Hello
{
    // value / method
    public static String staticValue;
    public String nonStaticValue;
}

class A
{
    Hello hello = new Hello();
    hello.staticValue = "abc";
    hello.nonStaticValue = "xyz";
}

class B
{
    Hello hello2 = new Hello(); // here staticValue = "abc"
    hello2.staticValue; // will have value of "abc"
    hello2.nonStaticValue; // will have value of null
}

这就是如何在所有类成员中共享值,而无需向其他类发送类实例Hello。而对于静态,你不需要创建类实例。

Hello hello = new Hello();
hello.staticValue = "abc";

你可以通过类名调用静态值或方法:

Hello.staticValue = "abc";
//Here is an example 

public class StaticClass 
{
    static int version;
    public void printVersion() {
         System.out.println(version);
    }
}

public class MainClass 
{
    public static void main(String args[]) {  
        StaticClass staticVar1 = new StaticClass();
        staticVar1.version = 10;
        staticVar1.printVersion() // Output 10

        StaticClass staticVar2 = new StaticClass();
        staticVar2.printVersion() // Output 10
        staticVar2.version = 20;
        staticVar2.printVersion() // Output 20
        staticVar1.printVersion() // Output 20
    }
}

静态方法不使用定义它们的类的任何实例变量。在这个页面上可以找到一个很好的解释

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

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