Java学习笔记四:static关键字
1.static表示什么?
static表示“全局”或者“静态”的意思。在Java中没有全局变量的概念,static 可以简单的理解为全局的,独立的一个功能。
(1)当我们在使用 static 修饰成员变量或者成员方法的时候,通常会在Java内存中为这些变量或者方法指定了一块独立的区域(这块区域可能在栈中,也有可能在堆中)。
(2)如果静态的变量或方法在不出其作用域的情况下,其 引用句柄是不会发生改变的。
(3)这块区域是内存共享的,它的引用都指向同一个位置,就是说如果我们修改引用指向的的值,这个值就被改变了;当其他对象使用这个值时,就是修改后的值。
代码:
public class Lesson_02_Static { public static int staticFiled = 0; public int notStaticFiled = 0; static { int staticBolckFiled = 0; } public Lesson_02_Static() { staticFiled++; notStaticFiled++; } public void print() { System.out.println("StaticFiled:" + staticFiled + ", NotStaticFiled:" + notStaticFiled); } public static void main(String[] args) { Lesson_02_Static ls1 = new Lesson_02_Static(); ls1.print(); Lesson_02_Static ls2 = new Lesson_02_Static(); ls2.print(); } }
输出结果:
StaticFiled:1, NotStaticFiled:1 StaticFiled:2, NotStaticFiled:1
它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。
因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象
2.static使用场景?
1.修饰静态变量(注意:不能是局部变量)。如:
public static int staticFiled = 0;
说明:
静态变量:被static修饰的变量,在内存中只有一份,在加载类的过程中完成静态变量的内存分配,不会随着类的实例化和增加。
实例变量:被static修饰的变量,当实例化类时,可以在内存中存在多个拷贝。
2.静态方法。如:
public static void main(String[] args) { Lesson_02_Static ls1 = new Lesson_02_Static(); ls1.print(); Lesson_02_Static ls2 = new Lesson_02_Static(); ls2.print(); }
说明:
(1)静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法。
静态方法中调用非静态方法提示错误,编译不通过;
非静态方法可以调用静态方法。
(2)因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
3.静态块。如:
static { int staticBolckFiled = 0; }
说明:
静态块位置可以随意放置,初始化顺序时不会随着位置变化而变化。一般情况下,会放在成员变量结束,类方法的开始的地方,方便理解。
3.static初始化
(1)初始化顺序是从类的开始到结尾查找static块,并且比类自身构造函数要早。
class StaticInit { public static int staticFiled = 0; public int notStaticFiled = 0; static { System.out.println("First Init"); } public StaticInit() { System.out.println("structure Init"); } public static void main(String[] args) { new StaticInit(); } static { System.out.println("Second Init"); } }
输出结果:
First Init
Second Init
structure Init
(2)static变量的初始化仅能一次
class StaticInt2 { T1 t1 = new T1(2); T1 t3 = new T1(4); T1 t2 = new T1(3); public StaticInt2() { System.out.println("t1: " + t1.t); System.out.println("t2: " + t2.t); System.out.println("t3: " + t3.t); } public static void main(String args[]) { new StaticInt2(); } } class T1 { static int t = 1; T1(int b) { t = b; } }
输出结果:
t1: 3 t2: 3 t3: 3
t的值在最后被设置为3,说明静态变量不会根据new 实例化而初始化(即不会在new时初始化值1).
说明:
在实际debug过程中,静态块中的方法先执行,然后在执行构造函数,最后执行成员变量的初始化。
总结:
static 指定的是一个固定的位置,在内存中只有一份;
在初始化时,优先执行static块。