Static关键字:
可以用来修饰类中的属性、类中的方法、以及具体的某一个类。
1、用于修饰属性:
则表示该属性属于整个类,不论有多少个对象实例,所有的实例共同拥有一个static静态的成员变量。该变量属于整个类,而并非是某个具体的实例,直接通过类名就可以访问对应的成员变量。
2、用于修饰方法:
用static修饰的方法称为静态方法,被修饰的静态方法可以通过一个实例来直接进行方法调用,也可以通过类名来直接调用类的静态方法。
关于静态方法的继承问题:
静态方法是可以被继承下来的,但是静态方法的子类不可以重写父类的静态方法。具体调用的是子类的静态方法还是父类的静态方法要看引用的类型,是子类的引用就调用子类的静态方,是父类的引用就调用父类的静态方法。
还有一点要注意,不可以在静态方法中访问非静态的成员变量,用反证法的思想,假设全可以访问,比如在静态方法中修改了某个属性的值。对于静态方法的访问是通过 类名.静态方法名的方式来进行的,如果再这个方法中对于某个非静态的属性做了修改,那这个类的众多实例中到底哪个实例中的属性进行了修改哪个没有进行修改,这个是说不清的。所以静态方法是不能访问非静态的成员变量的,静态方法只能访问静态的成员变量,非静态的方法各种类型的成员变量全都可以访问。
另外有一个要注意,static方法中是不能使用this的,因为this表示当前的对象的引用,即使一定指代的是某一个对象,而静态方法通过变量名来访问的时候根本无法确定到底是哪一个对象进行的调用,因为静态放啊属于整个类,因此静态方法中不能使用this,这样会报错的。
父类和子类之间有继承关系(extends)的方法,只能是全是静态或者是全是非静态,其他的几个种情况下都会报错。
Final关键字:
可以用来修饰类、方法、或者属性。
1、当一个类被final修饰的时候,比奥斯该类的终态,说明这个类不可以再被继承
2、当一个方法被final修饰的时候,表示该方法为终态方法,这个方法不可以被重写(override),否则会报错。
3、当一个属性被final修饰的时候,表示这个属性不可以被重新改写。这里要注意一下,final修饰属性的时候是一定要赋给一个初值的。如果对应的属性是一个引用,说明这个引用不可以被改写,表示这个引用不可以指向其他的对象了,这个引用只能指向初始的时候被声明的那个对象,不能指向新的对象了,但是所指向的对象的值是可以改变的,这里要注意区别。
由于final属性在初始化的时候必须要赋值,一种是在声明变量的时候直接赋好值,也可以在该类的构造方法中给final属性来赋值。
关于static代码块
静态代码块先于构造方法执行,从硬盘上把.class文件加载到java虚拟机上的时候,static静态代码块就已经算是执行了,而类中具体自己所写的构造方法仅仅是在生成对象的时候才执行。
对于下面这个例子,B类以及C类分别继承A类,但是A类的static代码块仅仅执行了一次,因为A类仅仅被加载了一次。
package statictest; class A{ static{ System.out.println("this is class A"); } public A(){ System.out.println("this is the constructor of class A"); } } class B extends A{ static{ System.out.println("this is class B"); } public B(){ System.out.println("this is the constructor of class B"); } } class C extends A{ static{ System.out.println("this is class C"); } public C(){ System.out.println("this is the constructor of class C"); } } public class test { public static void main(String[] args) { B b1=new B(); C c=new C(); B b2=new B(); } }
输出:
this is class A
this is class B
this is the constructor of class A
this is the constructor of class B
this is class C
this is the constructor of class A
this is the constructor of class C
this is the constructor of class A
this is the constructor of class B
通过结果可以看出来,上面的程序会一次执行A、B、C三个类的static块,执行的顺序是从父类到子类依次执行。从运行的结果中也可以看出来,静态的代码块是.class文件被加载的时候自动执行的,而构造函数是在生成一个新的对象的时候被调用的,顺序也是先执行父类的构造函数再执行子类的构造函数。后面生成了两个B的实例对象,但是静态代码块没有再被执行,这就可以看出来每一个类的静态代码块仅仅被加载一次,而构造函数是可以被执行多次的。