目录
java中static关键字的解析
1. static详解
1.1为什么要用static?
1.2 static的用法
1.2.1 static变量
1.2.2 static方法
1.2.3 static代码块
2.static面试总结
非静态方法和非静态成员变量,需要通过new一个对象才能调用,但是有时候需要不新建对象的情况下就可以用,则需要static
用static修饰的成员变量和成员方法都可以通过类名.的方式调用
Math类作为工具类,为了使用方便,所以都定义为static 可以直接Math.来调用
在《java编程思想》一书中,对static的解释如下:
“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”
主要用途:在没有创建任何对象的前提下,通过类本身来调用static方法
static修饰成员变量、成员方法(不修饰局部变量)、另外可以编写static代码块来优化程序性能。
静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static数据初始化的具体过程:下面例子来源于《java编程思想》(这部分看着有点多 不过没关系 一步一步看 就懂啦)
下面有四个类,红色框里包含程序入口,所以从红色框开始
StaticInitialization类开始,程序执行步骤如下:
第一步:初始化静态成员table,new动作使得Table类被加载
Table类被加载,静态变量先初始化,Table中的bowl1首先被初始化,此时Bowl类被加载
Bowl类被加载 Bowl类无静态变量和实例变量 调用构造函数 此时打印bowl1 回到Table类
Table中的bowl2接着被初始化,此时Bowl类被加载,同上一步, 打印bowl2 回到Table类
程序执行到构造函数 打印table() 调用f1(1) 打印f1(1) 此时table创建完毕 回到主程序 执行下一步 创建cupboard
第二步:初始化静态成员cupboard,new动作使得Cupboard类被加载
Cupboard类被加载,静态变量先初始化,Cupboard中的bowl4首先被初始化,此时Bowl类被加载
Bowl类被加载 Bowl类无静态变量和实例变量 调用构造函数 此时打印bowl4 回到Cupboard类
Cupboard中的bowl5接着被初始化,此时Bowl类被加载,同上一步, 打印bowl5 回到Cupboard类
Cupboard中的实例变量bowl3接着被初始化,此时Bowl类被加载,同上一步, 打印bowl3 回到Cupboard类
程序执行到构造函数 打印Cupbpard() 调用f1(2) 打印f1(2) 此时cupboard创建完毕 进入main函数
第三步:进入main函数
打印"creating new cupboard() in main"
创建cupboard新对象参考第二步 此时Cupboard已经在第二步被加载 此时Cupboard中的静态变量不在被初始化 但是实例变量会被初始化 此时打印bowl3 执行构造函数再打印Cupbpard() 调用f1(2) 打印f1(2) 回到main()
回到main后 重复蓝色部分操作一次 则打印为"creating new cupboard() in main" 、 bowl3 、Cupbpard()、f1(2) 回到main
回到main 调用f2() 打印f2(1) 调用f3() 打印f3(1)
由此全过程操作完成 最终的打印顺序按照红色字体排序下来便是以下结果:
总结:初始化顺序是:先静态变量(尚未因前面的创建对象被初始化)、再是非静态变量、最后是构造函数(若要创建对象,对象中的初始化,会覆盖掉类初始化,这句话的解释看下图)
可以访问 | 不可以访问 | |
静态方法 | 静态方法、静态变量 | 非静态方法、非静态成员 |
非静态方法 | 非静态方法、非静态成员、静态成员、静态方法 |
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次,所以很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
答:不会 java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字
答:可以 静态方法中 不能使用this 但是在非静态方法中 可以用this访问成员变量,如下图
将持续更新
参考资料:https://java-worker-cr.iteye.com/blog/2166472