→阿童沐

財富==支撐一個人生存多長時間的能力!

导航

<Java SE 详解> static与final使用陷阱-

1、static关键字:可以用于修饰属性,也可以用于修饰方法,还可用于修饰类。

  a> static修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量,即静态成员变量是属于类的,而不是某一个特定的对象的。一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。

  如果一个成员变量是static的,那么我们可以“类名.成员变量名”的方式来使用它(Java推荐使用这种方式访问静态成员)。

  b> static修饰方法:static修饰方法叫做静态方法,对于静态方法来说,可以使用“类名.成员方法名”进行访问。

 

2、静态方法(static method)只能被继承或者是隐藏(hide),而不能被重写(override)。静态方法遵守覆盖或隐藏的特性,而不像实例方法中的重写或覆写特性。在实际开发中很少碰见这种隐藏的使用情况。

详见:http://docs.oracle.com/javase/tutorial/java/IandI/override.html

如下例:

package cn.edu.bupt.staticTest;

public class StaticTest {
public static void main(String[] args) {
N n = new N();
n.output(); //output "N"

System.out.println("-----------------");

M m = new N(); //output "M"
m.output();
}
}

class M {
public static void output() {
System.out.println("M");
}
}

//静态方法可以被继承,可以被hidden,但是不可以被override,在实际开发中很少碰见这种情况.
class N extends M {
//Hide the class method in M, not override
public static void output() {
System.out.println("N");
}
}

 

3、final关键字:final可以修饰 属性、方法、类。

  a> final修饰类:当一个类被final所修饰时,表示该类是一个终态类,即不能被继承;

  b> final修饰方法:当一个方法被final所修饰时,表示该方法是一个终态方法,即不能被重写(实例方法)(override)以及(隐藏)(类方法)(hide);

  c> final修饰属性:当一个属性被final所修饰时,表示该属性不能被改写,即变量内部的内容不能被改变,对于final类型成员变量,必须要进行显式赋初值,否则会发生编译错误

例:  二十三-43:00

package cn.edu.bupt.staticAndfinal;

public class FInalTest {

public static void main(String[] args) {

People people = new People();
people.address = new Address(); //final引用变量内所存的对象地址被改变,编译错误
people.address.name = "shanghai"; //所指对象的内容(name)发生改变,但是对象在内存中的地址并未改变
}
}

class People {
public final Address address = new Address();
}

class Address {
public String name = "beijing";
}

说明:

final修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化(比如说不能从10变为20);如果final修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。

对于final成员变量的各种错误见  二十四-02:00

final成员变量初始化方式:

  a> 在定义final变量的时候同时赋初值;

  b> 在定义final变量的时候不赋初值,但是需要在该类中的所有的构造方法中给该final类型的成员变量赋初值。  二十四-06:30

 

4、static代码块:静态代码块。静态代码块先于构造方法执行,是在类被加载入Java虚拟机的时候执行static代码块的。

如下例:

package cn.edu.bupt.staticAndfinal;

public class StaticTest2 {
public static void main(String[] args) throws Exception {
//Class<?> classType = P.class;
//Object o = classType.newInstance();
new S();
}
}

class P {
static {
System.out.println("P static block");
}

public P() {
System.out.println("P Constructor");
}
}

class Q extends P {
static {
System.out.println("Q static block");
}

public Q() {
System.out.println("Q Constructor");
}
}

class S extends Q {
static {
System.out.println("S static block");
}

public S() {
System.out.println("S Constructor");
}
}

最终输出的结果是:

解释:

当new S()的时候首先需要加载类S,然后才是实例化S类,即S的静态代码块先于构造方法执行;

但是S是Q的子类,因此需要加载Q,Q是P的子类,又需要加载P,因此需要执行P的静态代码块,再Q,再S;

S的静态代码块执行完成,随后开始执行S的构造方法;

S是Q的子类,Q是P的子类,因此构造方法执行顺序为PQS,这样合起来执行顺序为 PQS - PQS。

 

5、不能在静态方法或静态代码块中使用this关键字。

 

 

posted on 2012-02-17 16:07  阿童沐  阅读(222)  评论(0)    收藏  举报