应聘的时候,老是会有关于static的考题。看了前几章我才发现,以前自己都是死记硬背的……根本没有理解所以然。
理解static,首先要理解一个对象的创建过程。
引用<Thinking in java>的话:创建一个对象的过程,假设有一个类就叫做Dog。
1、即使没有显式的使用关键字,构造器实际上是静态方法。因此,在首次创建Dog对象或者调用Dog的静态方法/域时,java解释器必须查找Dog.Class的路径
2、载入Dog.Class(浙江创建一个Dog对象),有关静态初始化 的动作将执行,因此,静态方法/域只在第一次加载时执行。
3、当用 new Dog()创建一个Dog对象时,首先在堆栈上为该对象创建足够的存储空间
4、这个存储空间将清零,所有基本类型的数据将赋予默认值,引用将赋值为null。
5、执行所有定义初始化的动作
6、执行构造器。
在了解了对象创建过程后,理解static的原理就要简单得多。如下例子:
public class Test {
public static void main(String[] args) {
System.out.println("come into inside");
Cups cups1 = new Cups();
cups1.cup1.p();
Cups cups2 = new Cups();
}
}
class Cup{
Cup( int k ){
System.out.println("第"+k+"个");
}
public void p(){
System.out.println("===================");
}
}
class Cups{
static Cup cup1, cup2;
static{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups(){
System.out.println("cups");
}
}
输出为:
第1个
第2个
cups
===================
cups
由此可见static代码块只执行了一次 ,并且是在构造器执行之前,类加载时就执行的。
*************注意以下两个关于继承和static的程序:
程序1:
public class Test{
public static void main(String[] args) {
Test t = new Test();
Animal a = new Dog();
System.out.println(a.getName());
}
}
class Animal{
Animal(){}
public static String getName(){ // -----1----
return "animal";
}
}
class Dog extends Animal{
Dog(){}
public static String getName(){ //----2----
return "dog";
}
}
输出是: animal
如果将两个getName()的方法的static 都去掉,则输出为:dog 此时是重写方法
可见,static修饰的方法是不具有多态性。但是,如果只是将1或者2中的static去掉,是不行的。