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

package hello;

public class Hello {

    Clock clock = new Clock();

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

但是它给出了错误

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

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

static Clock clock = new Clock();

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


当前回答

在Java中,static关键字可以简单地视为表示以下内容:

“不考虑或与任何特定情况有关”

如果你以这种方式思考static,就更容易理解它在各种上下文中的用法:

静态字段是属于类而不是任何特定实例的字段 静态方法是一种没有这种概念的方法;它在类上定义,并且不知道该类的任何特定实例,除非将引用传递给它 静态成员类是一个嵌套类,没有任何关于其外围类实例的概念或知识(除非将对外围类实例的引用传递给它)

其他回答

静态成员的基本用法…

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";

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

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


旁注

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

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

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

// Clearer
Thread.sleep(5000);

理解静态概念

public class StaticPractise1 {
    public static void main(String[] args) {
        StaticPractise2 staticPractise2 = new StaticPractise2();
        staticPractise2.printUddhav(); //true
        StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */

        StaticPractise2.printUddhavsStatic1(); //true
        staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static  things and it organizes in its own heap. So, class static methods, object can't reference */

    }
}

二等

public class StaticPractise2 {
    public static void printUddhavsStatic1() {
        System.out.println("Uddhav");
    }

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}

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

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

输出:编译时错误

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

这意味着静态字段只有一个实例存在[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或线程一个,但这不是重点。