对于用static修饰的变量称为静态变量,也叫类变量。由类创建的所有对象都可以共用这个变量。类变量随着类的加载而加载,即使此类还未new过对象,这个类变量也存在,而且仅一份。
顺便说一下实例变量,实例变量是类new了一个对象之后才有的,每个对象有自己的那一份。
当一个方法或者变量需要初始化加载,或者是经常被调用的时候可以加上static。用static修饰的方法可以用类名直接调用,不用的一定要先实例化一个对象然后才可以调用。
用static修饰的方法叫静态方法,也叫类方法。
随着类的加载而加载,就算没有new一个对象,类方法还是存在,且仅存在一份。
类方法内部可以调用静态的变量和静态的方法,而不能调用非静态的变量和方法;反之,非静态方法可以调用静态的变量和方法。
结合代码理解一下:
public class ExtB{
/*类变量和实例变量都是全局变量,无须初始化
* 两者的区别是:
* 类变量由static修饰,由所有对象共享
* 实例变量不用static修饰,由每个对象各自占有自己的,类似于在实例化时创建了实例变量的副本
* */
static int i = 10;//不必须初始化
int j = 20 ;//不必须初始化
public ExtB(int j) {
this.j = j;
}
public ExtB() {
}
public void hello(){
System.out.println("Hello,我是非静态方法~");
System.out.println("Hello,我是非静态方法~我在调用类变量i= " + i);
System.out.println("Hello,我是非静态方法~我在调用实例变量j= " + j);
System.out.println("Hello,我是非静态方法~我在调用静态方法helloStatic()");
helloStatic();
}
public void hello1(){
hello();//非静态方法调用非静态方法没有问题
System.out.println(j);//非静态方法调用非静态变量没有问题
}
public static void helloStatic() {
System.out.println("Hello,我是静态方法~");
System.out.println("Hello,我是静态方法~我在调用类变量i= " + i);
//System.out.println("Hello,我是静态方法~我在调用实例变量j= " + j);//报错,非静态变量不能直接调用
}
public static void main(String[] args) {
int x;//局部变量必须初始化
ExtB extb1 = new ExtB(30);
ExtB extb2 = new ExtB(40);
System.out.println("ExtB.i= "+ExtB.i);
System.out.println("extb1.i= "+extb1.i);
System.out.println("extb2.i= "+extb2.i);
System.out.println("--------------------");
//System.out.println("ExtB.j= "+ExtB.j);//报错,非静态变量不能直接调用
System.out.println("new ExtB(1).j= "+new ExtB(1).j);
System.out.println("extb1.j= "+extb1.j);
System.out.println("extb2.j= "+extb2.j);
System.out.println("--------------------");
//System.out.println(x);//报错,局部变量必须初始化
ExtB.helloStatic();//调用静态方法,没有问题,或者直接helloStatic();也行
System.out.println("--------------------");
//hello();//报错,非静态方法不能直接调用
new ExtB().hello();
System.out.println("--------------------");
}
}
再给一个单例模式一种写法:
class Single {
private static Single single = null;
public static Single getInstance(){
synchronized (Single.class) {
if (single == null) {
single = new Single();
}
}
return single;
}
}