static关键字的作用
static意思是全局、静态,用来修饰成员变量、成员方法、代码块。static所修饰的内容,可在整个程序内被所需要它的对象直接调用。静态成员的数据保存在内存的数据共享区,并不单独保存在每个对象的内存中,因此极大地节省了空间,优化了代码结构,提高了运行效率。
1.static修饰成员变量
1.1静态成员变量的访问方式:
假设使用static修饰Demo2类内的某一个成员变量a,则a应该被通过静态方式访问,即通过其类名Demo2进行访问。如果通过类对象demo2访问,会提示警告!
class Demo2{
//创建并初始化一个静态成员变量a
public static int a = 1;
}
public class Demo1 {
public static void main(String[] args) {
//创建一个Demo2的类对象
Demo2 demo2 = new Demo2();
//通过静态成员变量所在的类的类对象调用该变量
System.out.println(demo2.a);
}
}
警告:The static field Demo2.a should be accessed in a static way
(使用static修饰的A类内的B成员变量,应该通过静态方式访问)
程序运行结果为:1
虽然此时程序也可以运行,但是会出现警告,因此不建议使用类对象调用。
1.2静态成员变量使用类名调用是没有任何的问题。
与普通成员变量不同,普通成员变量需要通过类对象调用而不能直接通过类名调用,但是静态成员变量直接通过类名调用没有任何问题,或者说静态成员变量就应该通过类名调用。
class Demo2{
//创建并初始化一个静态成员变量b
public static int b = 1;
}
public class Demo1 {
public static void main(String[] args) {
//打印通过类名调用的静态成员变量
System.out.println(Demo2.b);
}
}
运行结果:1
1.3静态成员变量和当前类的类对象毫无关系。
- 在代码中没有创建对象时,可以通过类名直接使用静态成员
- 代码中对象已经被JVM的GC销毁时,依然可以通过类名调用静态成员变
1.4静态成员变量的修改
不管通过哪一种方式调用静态成员变量,修改对应的静态成员变量数据,所有使用到当前静态成员变量的位置,都会受到影响。
2.static修饰成员方法
2.1调用方式:
与静态成员变量调用方式相同,静态成员方法也推荐使用静态方式调用,即通过类名调用
2.2使用其他成员
1.静态成员方法中不能使用非静态成员 ,包括非静态成员方法和非静态成员变量。【因为没有对象】
class Demo2{
//创建并初始化一个非静态成员变量c
public int c = 1;
//创建静态成员方法
public static void method() {
//使用非静态非成员变量
System.out.println(c);
}
}
public class Demo1 {
public static void main(String[] args) {
}
}
程序报错!
提示:Cannot make a static reference to the non-static field c
(不能对非静态字段c进行静态引用)
- 静态成员方法中不能使用this关键字。【因为没有对象】
- 静态成员方法中可以使用类内的其他静态成员。【因为大家都是静态的,是同类】
- 静态成员方法中可以通过new 构造方法创建对象
3.static修饰代码块
代码块:
构造代码块:初始化当前类的所有类对象,只要调用构造方法,一定会执行对应的构造代码块。
静态代码块:初始化程序,只要类文件加载,静态代码块中所有内容全部执行。
局部代码块:提高效率,解决内存,让JVM回收内存的效率提升。
4.使用及执行规则
4.1修饰内容
static只能修饰以上三个,一般不能修饰类,只有一种特殊用法可以用static修饰内部类,但普通类不能用static修饰。
4.2执行顺序
所有的static修饰的内容在整个程序中执行优先级最高(不论在代码里的顺序如何),其次是main()方法,然后是构造代码块,最后普通代码。
一个顺序题:
public class Demo1 {
{
System.out.println("构造代码块");
}
static {
System.out.println("静态代码块");
}
public Demo1() {
System.out.println("构造方法");
}
public static void main(String[] args) {
System.out.println("main方法");
Demo1 demo1 = new Demo1();
}
}
执行结果:
静态代码块
main方法
构造代码块
构造方法