static关键字详解

Java中static关键字用来修饰3类东西:变量,代码块,函数。

1.变量

static修饰的变量叫类变量/静态变量,对于类变量/静态变量在内存中只有一个拷贝(节省内存),JVM只分配一次内存,在加载类的过程中完成类变量/静态变量的内存分配,可用类名直接访问,也可以用new生成对象后访问。

2.代码块

static修饰的代码块叫静态代码块,是类中独立于类成员的代码块,在类中可以存在多个,位置任意,但不能存在于函数内部。JVM在加载类时执行该代码块,如果有多个静态代码块则按照它们在类中出现的顺序执行,且只执行一次,常用来完成初始化工作。

3.函数

static修饰的函数叫静态函数,被调用的时候不需要实例化对象,执行通过类名可以访问。它只能访问static修饰的函数和变量,不能访问其他需要实例化的成员,因此该类函数的内部不能出现this和super关键字。

java中类的加载步骤:

使用类是时,首先由ClassLoader将要使用的类加载进来。这个过程要经过三个步骤完成:装载、链接、初始化,其中链接有分为,校验、准备和解析三步。除解析外其他步骤严格按照顺序执行。这些步骤要完成的功能如下:

装载:查找和导入类或接口的二进制数据;

校验:检查导入的类或接口的二进制数据的正确性;

准备:给类的静态变量分配内存空间并初始化;

解析:将符号引入转化成直接引用,可选步骤;

初始化:激活类的静态变量的初始化代码和静态代码块。

关于静态代码块的初始化工作是各类面试中常考的知识点,下面通过一个简单的例子进行说明。

public class Parent {
    static String name = "Parent";
    {
        System.out.println("Parent no static code block");
    }
    static {
        System.out.println("Parent static block");
    }
    public Parent(){
        System.out.println("Parent constructor");
    }
}

public class Child extends Parent {
    static String childName = "Child";
    {
        System.out.println("Child no static block");
    }
    static {
        System.out.println("Child static block");
    }
    public Child(){
        System.out.println("Child constructor");
    }
}

public class Client {
    public static void main(String[] args){
        Child child = new Child();
    }
}

如上代码经过编译运行后的输出结果如下:

Parent static block
Child static block
Parent no static code block
Parent constructor
Child no static block
Child constructor

通过上面的例子,我们可以了解到当new Child()时,执行顺序如下:1.父类的静态代码块,2.子类的静态代码块,3.父类的非静态代码块,4.父类的构造函数,5.子类的非静态代码块,6.子类的构造函数。

所以说new一个对象时,对象的初始化顺序是:如果父类有静态代码块,首先执行父类的静态代码块;如果子类有静态代码块,接着执行子类的静态代码块。如果父类有非静态代码块,再执行父类的非静态代码块,接着执行父类的构造函数。如果子类有非静态的代码块,再执行子类的非静态代码块,接着执行子类的构造函数。总结一句话就是:先执行父类的静态代码再执行子类的静态代码;接着执行父类的非静态代码和构造函数;接着执行子类的非静态代码和构造函数。

注意:调用子类的构造方法时,默认的是先查找父类不带参数的构造方法,若父类没有不带参数的构造方法,则必须在子类的构造方法中通过super关键字显示的调用,否则编译过程中会出错。

posted @ 2014-04-05 21:53  blackcat_333  阅读(184)  评论(0编辑  收藏  举报