static可以声明静态变量、静态方法、静态类、代码块。
静态变量:
当我们需要一个可以全局访问的对象时, 我们首先想起静态变量/对象, 因为它是当前进程中的唯一引用, 但不一定是唯一对象(看看多线程时的单例模式就明白了)。
代码很简单: public static int value或Object obj。
静态方法:
就是在类成员方法前添加static关键字, 从而在其它类可以直接引用该方法, 不再通过类实例找到该方法。、
例如:public class Demo {
public static void method() {
}
}
静态类:
只能定义在一个外部类中, 即只有静态内部类, 见其它博文介绍, 项目中很少使用(单例模式可能会用到)。
代码块:
有时需要只需要执行一次若干行代码, 这时可以用静态代码块, 加载含有静态代码类时1. 先执行类静态成员变量, 2. 再执行静态代码块。 3. 执行类构造函数。
例如: public class demo {
private int a;
... //声明类成员变量
static {
method1();
method2();
}
}
写的比较少, 我们通过示例代码加深对static的理解:
代码1:
public class FatherClass {
public static void show() {
System.out.println("FatherClass show: ");
}
public static void showExt() {
System.out.println("FatherClass showExt");
}
}
public class ChildClass extends FatherClass {
public static void show() {
System.out.println("ChildClass show"); //静态方法也能覆盖???会是多态吗? 仔细考虑一下
}
}
FatherClass.show();
ChildClass.show();
FatherClass obj = new ChildClass();
obj.show();
obj.showExt();
想想会输出什么? obj.show()输出父类还是子类的方法?
FatherClass show:
ChildClass show
FatherClass show:
FatherClass showExt
很意外吗? 静态方法是不能被继承或者覆盖的, 子类保存了父类的引用, 所以能调用父类的方法(如showExt函数)。当父类、子类都有相同方法时(如show函数), 调用时只会找声明该对象的类(如FatherClass)中的方法。
再看个例子:
class A {
private B b = new B();
private static C c = new C();
public A() {
System.out.println("A construct");
}
static {
System.out.println("A static");
}
}
class B {
public B() {
System.out.println("B construct");
}
}
class C {
public C() {
System.out.println("C construct");
}
}
public class MapMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a;
a = new A();
a = new A();
}
}
A a这行代码会有输出吗? 答案是没有, 因为还没有真正的加载类A。
第一行a = new会输出什么?先看答案。
C construct
A static
B construct
A construct
我们看到了, 当加载一个类时先执行类静态变量、再静态代码块、类成员变量、构造函数等。
那么第二a = new A()呢? 因为前面说静态变量只有一个,静态代码块只执行一次, 所以会输出
B construct
A construct
我们看到类静态成员对象只会实例化一次, 这也是用它实现线程安全单例模式的原因。