具体来说,我正在尝试以下代码:
package hello;
public class Hello {
Clock clock = new Clock();
public static void main(String args[]) {
clock.sayTime();
}
}
但是它给出了错误
不能访问静态方法主中的非静态字段
所以我把时钟的声明改为这样:
static Clock clock = new Clock();
这招奏效了。将该关键字放在声明之前意味着什么?它究竟会做什么和/或限制可以对该对象做什么?
这里有一个问题是关于这个概念中“静态”一词的选择。这个问题已经解决了,但我认为词源问题还没有明确解决。所以…
这是由于关键字重用,从C开始。
考虑C语言中的数据声明(在函数体中):
void f() {
int foo = 1;
static int bar = 2;
:
}
变量foo在输入函数时在堆栈上创建(并在函数终止时销毁)。相比之下,bar总是在那里,所以在普通英语中它是“静态的”——它不会去任何地方。
Java和类似的语言对数据有相同的概念。数据可以为类的每个实例(每个对象)分配,也可以为整个类分配一次。因为Java的目标是为C/ c++程序员提供熟悉的语法,所以这里使用“static”关键字是合适的。
class C {
int foo = 1;
static int bar = 2;
:
}
最后,我们来谈谈方法。
class C {
int foo() { ... }
static int bar() { ... }
:
}
从概念上讲,类c的每个实例都有一个foo()实例,整个类c只有一个bar()实例。这与我们讨论的数据的情况类似,因此使用'static'也是一个明智的选择,特别是如果你不想在你的语言中添加更多保留的关键字。
静态意味着您不必创建类的实例来使用与类关联的方法或变量。在你的例子中,你可以调用:
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类的每个实例都有不同的值/引用,因此不能从类的静态部分访问它。
关键字static用于表示一个字段或方法属于类本身,而不属于任何特定的实例。使用您的代码,如果对象Clock是静态的,那么Hello类的所有实例将共同共享这个Clock数据成员(字段)。如果使它是非静态的,那么Hello的每个实例都将有一个唯一的Clock。
您向Hello类添加了一个主方法,以便可以运行代码。这样做的问题是,主方法是静态的,因此,它不能引用其中的非静态字段或方法。你可以用两种方法来解决这个问题:
将Hello类的所有字段和方法设置为静态的,以便在主方法中引用它们。这不是一件好事(或者是将字段和/或方法设置为静态的错误原因)
在主方法中创建Hello类的实例,并以最初访问和使用它们的方式访问它的所有字段和方法。
对你来说,这意味着对你的代码进行以下更改:
package hello;
public class Hello {
private Clock clock = new Clock();
public Clock getClock() {
return clock;
}
public static void main(String args[]) {
Hello hello = new Hello();
hello.getClock().sayTime();
}
}
静态成员的基本用法…
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";