具体来说,我正在尝试以下代码:
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关键字属于该类的类的实例。
可用于将变量或方法附加到类。
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.
图片来源:最终静态
静态成员属于类,而不是特定的实例。
这意味着静态字段只有一个实例存在[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或线程一个,但这不是重点。
理解静态概念
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");
}
}