static关键字最基本的用法是:
1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来
2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来
定义
被static修饰的变量、被static修饰的方法统一属于类的静态资源,是类实例之间共享的,换言之,一处变、处处变。JDK把不同的静态资源放在了不同的类中而不把所有静态资源放在一个类里面。
重要知识点
静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的
几个问题
- 静态方法能不能引用非静态资源?不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。
- 静态方法里面能不能引用静态资源?可以,因为都是类初始化的时候加载的,大家相互都认识。
- 非静态方法里面能不能引用静态资源?可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。
静态块
静态块里面的代码只执行一次,且只在初始化类的时候执行
三个结论:
第一个结论:静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。
第二个结论:静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问。
第三个结论:静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次
public class A
{
private static int a = B();
static
{
System.out.println("Enter A.static block");
}
public static void main(String[] args)
{
new A();
}
public static int B()
{
System.out.println("Enter A.B()");
return 1;
}
}
打印结果是
Enter A.B()
Enter A.static block
得出第一个结论:静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。
因为先定义了private static int a = B();所以执行B(),先输出Enter A.B()
public class A
{
static
{
c = 3;
System.out.println(c);
}
private static int c;
}
这段代码的第6行是有错误的“Cannot reference a field before it is defined”。从这个例子得出第二个结论:静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问。
public class A
{
static
{
System.out.println("A.static block");
}
public A()
{
System.out.println("A.constructor()");
}
}
public class B extends A
{
static
{
System.out.println("B.static block");
}
public B()
{
System.out.println("B.constructor()");
}
public static void main(String[] args)
{
new B();
new B();
}
}
结果是
//第一次执行B();
A.static block
B.static block
A.constructor()
B.constructor()
//第二次执行B();
A.constructor()
B.constructor()
第三个结论:静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。
本文参考链接:https://www.cnblogs.com/swisszhang/p/9892992.html