关键字static作用如下:
1. 为某个基本数据类型或对象分配单一的存储空间。
2. 实现某个属性或方法与类关联。在类被加载后类名可以直接调用静态成员方法(下面简称静态方法)或者访问静态成员变量(下面简称静态成员变量)。对象也可以做到。
有4种使用情况:
1. 静态属性即静态成员变量
2. 静态方法
3. 静态代码块
4. 静态成员类
静态方法
因为静态方法不依赖于对象,所以静态方法内部不能使用this。因为非静态方法和非静态成员变量依赖于对象,所以静态方法内部不能调用非静态方法或者访问非静态成员变量。而非静态方法内部可以调用静态方法或者访问静态成员变量。静态方法只能定义在顶级类(不同于内部类)或者静态内部类里面。
空对象调用静态方法:
1 public class NullInvoker { 2 3 public static void testNullInvoker(){ 4 System.out.println("in testNullInvoker"); 5 } 6 7 public static void main(String[] args) { 8 NullInvoker NULL = null; // 虽然这里是空指针,但是下面依然可以执行下去 9 NULL.testNullInvoker(); // 正常运行 10 } 11 12 }
结果:
1 in testNullInvoker
静态方法不能被重写:
1 public class TestStaticMethod { 2 3 public static void main(String[] args) { 4 SubClass s = new SubClass(); 5 Parent p = s; 6 p.testStatic(); // 打印父类方法 7 s.testStatic(); // 打印子类方法 8 } 9 10 } 11 12 class Parent { 13 14 public static void testStatic() { 15 System.out.println("父类方法"); 16 } 17 18 } 19 20 class SubClass extends Parent { 21 22 public static void testStatic() { 23 System.out.println("子类方法 "); 24 } 25 26 }
结果:
1 父类方法 2 子类方法
静态成员变量
静态成员变量和非静态成员变量的区别是:静态成员变量被所有的对象所共享,在内存中只有一个副本,在类被加载时会被初始化。而非静态成员变量是单个对象所独有,在创建对象时被初始化,存在多个副本,各个对象拥有的副本互不影响。
静态代码块
仅在类被加载时会执行静态代码块。任何方法内部都不能使用静态代码块。
注意:Java语法规定static不能修饰局部变量。
笔试题
这段代码的输出结果是什么?
1 public class Test { 2 Person person = new Person("Test"); 3 static{ 4 System.out.println("test static"); 5 } 6 7 public Test() { 8 System.out.println("test constructor"); 9 } 10 11 public static void main(String[] args) { 12 new MyClass(); 13 } 14 } 15 16 class Person{ 17 static{ 18 System.out.println("person static"); 19 } 20 public Person(String str) { 21 System.out.println("person "+str); 22 } 23 } 24 25 26 class MyClass extends Test { 27 Person person = new Person("MyClass"); 28 static{ 29 System.out.println("myclass static"); 30 } 31 32 public MyClass() { 33 System.out.println("myclass constructor"); 34 } 35 }
结果:
1 test static 2 myclass static 3 person static 4 person Test 5 test constructor 6 person MyClass 7 myclass constructor
创建当前类的对象过程:先初始化成员变量,再执行构造器。
参考资料
关于静态方法为什么不能被重写的一点思考以及overload的一些坑。
《 Java程序员面试笔试宝典》 P80-83