java笔记 static关键字详解

时间:2022-05-26 16:51:25

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

static关键字

作       用:修饰符,用于修饰成员对象(成员函数、成员变量)代码块。切记:不可修饰局部对象(因为其优先级较高)

存放区域:被static修饰的对象,位于共享区内,而非堆内存中。

执行顺序:被static修饰的对象,随着类的加载而加载,且优先于主函数。

生命周期:和类一样,只要类还存在就一直驻留在内存当中。

用       法:1.修饰成员变量时,成员变量中储存的数据应为对象共有数据。

                          例如:人的性别,所有人都是男或女,所以我们没有必要每创建一个人的对象就在堆内存中存放人对象的内存块中再划分出一块内存来盛放相同的数据。

                   2.修饰成员函数时,因其执行顺序,故成员函数中不能访问非静态内容,当然就不能访问本类中的其他非静态对象了。

                          例如:工具类中的方法,我们只需要使用其方法,而不需要使用其类中的成员对象,就可把工具类函数定义为静态函数。

                   3.修饰代码块时,随着类的加载而加载,且只执行一次。

优  缺  点:根据以上特点可以看出。

    优点:可以修饰对象共有的数据以节省内存空间,修饰工具函数,使其可直接通过类名打点的方式调用,免去创建无用对象。

    缺点:生命周期太长,使用不当容易造成在内存中驻留,不释放内存。且被其修饰的对象中不能包括非静态对象。

综合实例:

class Person {
String name;//不使用静态是因为每个人的名字不都是相同的。
static String country="China";//中国人使用本程序时,国籍均为中国,若都存放在堆内存中会造成内存的浪费。

public static void show(){
//System.out.println("name:"+name);
//上述语句在编译时会引起错误,因为本方法在类加载的过程中就以完成加载,而此时name变量还未加载到内存中,故此时访问会造成异常
System.out.println("My country is:"+country);//此语句编译时不会出现问题,因为country变量时静态变量,根据代码的执行顺序,其已被加载
}

/*
*以下为Person类的静态代码块
*/
static
{
System.out.println("I am the Person static blocks");
}

/*
*以下为构造代码块 ,作用是初始化构造
*/
{
System.out.println("At this point name is:"+name);//构造代码块优先于构造函数执行,但并非随着类的加载而加载,故此处可以访问非静态变量
}

public Person(String name){
System.out.println("My name is:"+name);
}
}
class StaticDemo{
/*
*以下为StaticDemo类的静态代码块
*/
static
{
System.out.println("I am the StaticDemo static blocks");
}
public static void main(String[] args) {
Person.show();
Person p = new Person("si Li");
}

}

运行结果为:

I am the StaticDemo static blocks
I am the Person static blocks
My country is:China
At this point name is:null
My name is:si Li

程序执行分析:

1.首先jvm加载StaticDemo类,故此时StaticDemo类中的静态代码块被加载,打印出第一句话。

2.接着执行main函数,main函数中,第一条执行语句是Person.show(),调用了Person类中的静态方法,此时jvm首先加载Person类,故Person类中的静态代码块先被加载,故打印出第二句话。

3.紧接着执行Person类中的静态show()方法,故打印出第三句话。注意:此时构造代码块并未执行,因为其优先级低于静态函数。

4.这时执行main函数中的第二条语句,创建一个带有name的Person对象,因构造代码块执行在且仅在构造函数之前,故此时先执行构造代码块,故此时打印出第4句话,因为构造函数还未执行,故name值为null。

5.构造函数执行,故打印出第五句话。

 

总结:static执行的优先级较高但生命周期过长,故有利有弊,应在合适的应用场景下使用,以提高代码的执行效率。