static关键字(记住:静态与对象无关)
5.1静态代码块
用static修饰的代码块称之为静态代码块:
public class Test {
public int a;
static{ //用static修饰的代码块称之为静态代码块
System.out.println("我是静态代码块");
}
{ // 构造代码块
System.out.println("我构造代码块");
}
public Test(){//构造方法
System.out.println("我是构造方法");
}
}
(类成员、类方法就是指静态成员、静态方法)
注意:
静态代码块只有在类第一次加载到内存的时候执行一次。
构造代码块在每次new对象的时候执行一次,并执行在构造方法之前。
静态代码块最先执行,然后构造代码块执行,再构造方法执行。
静态代码块和构造代码块都可以有多个,多个时分别按顺序执行。
//笔记: public class Main{ public static void main(String[] args){ System.out.println(A.a); } } class A{ public static int a=5; static{ System.out.println("静态代码块执行了。。。"); a=7; System.out.println(A.a); System.out.println("静态代码块执行结束。。。"); } public A(){} public static void fun(){} } //执行结果 静态代码块执行了。。。 a=7 静态代码块执行结束。。。 a=7 //分析执行过程 1.main方法程序的入口,首先压入栈桢, 2.执行main中的System.out.println(A.a); 首次调用类A,会在方法区(永久区)加载类, 3.加载类A时会加载类A的所有信息, 首先加载类的静态属性a,并会先初始化为默认值0,不会立即执行赋值操作; 再加载类的静态方法(加载不是执行) 4.先执行赋值a=5;再执行静态代码块,因为静态属性a的赋值操作在前, (言外之意:静态属性初始化语句和静态代码块是同级的,按顺序执行) //注意:这静态属性初始化与静态代码块换位置后结果: static{ System.out.println("静态代码块执行了。。。"); a=7; System.out.println(A.a); System.out.println("静态代码块执行结束。。。"); } public static int a=5; //执行结果 静态代码块执行了。。。 a=7 静态代码块执行结束。。。 a=5 //分析:静态属性初始化语句和静态代码块是同级的,按顺序执行
5.2 静态属性
用static修饰的成员变量,叫静态成员变量。(静态域、静态属性)。
例如:
//静态属性变量名一般全大写
public static int COUNT; //声明一个静态的整型成员变量。
注意:
静态变量只有在第一次加载类到内存的时候初始化一次。
static只能修饰成员变量,不能修饰局部变量。
5.3 静态方法
用static修饰的方法,叫静态方法。
例如:
public static int fun(){
System.out.println("我是静态方法");
}
public int fun(){
System.out.println("非静态方法、实例方法、普通方法");
}
不用static修饰的方法,在很多地方也称之为非静态方法、实例方法。
注意:静态方法内访问本类的 属性和方法 必须也是静态的。
总结:
在类中,用static声明的成员变量为静态成员变量,在类第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份,它是该类的公用变量,也叫类变量或类属性。
用static声明的方法为静态方法,该方法独立于类的实例,所以也叫类方法。
静态方法中只能调用本类中其他的静态成员(变量和方法)。
静态方法中不能使用this和super关键字。
静态成员(类成员)可以通过类名直接访问,也可以通过类的对象去访问。但是强烈建议通过类名访问静态成员。
5.4 static 内存分配:
静态区:
又叫方法区,不属于堆,也不属于栈,类似堆一样,被所有的线程共享。方法区包含所有的class和static变量。
方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
参考上节课内存分配 方法区的说明