static关键字和静态代码块
static关键字
1、 可以修饰成员变量,成员方法
那么都知道static关键字主要的意思是静态的,它可以用来修饰成员变量和成员方法
- 一,被static修饰的变量,属于类变量,可以通过类名.变量名进行调用,而不需要new一个对象进行调用。
- 二,被static修饰的方法,属于类方法,可以通过类名.方法名进行调用,不需要new一个对象调用。
- 三、被static修饰的类,这是一种特殊用法,用来修饰内部类的。
2、 随着类的加载而加载,优先于对象加载
- 静态资源属于类,但是是独立于类的存在,从Jvm类加载机制来说,静态资源是在类初始化时候加载的,而非静态资源是在类new实例化对象是加载的。那么可以发现静态资源的加载是优于对象加载的,当类被初始化时,静态资源就会被加载
3、 只加载一次,就会一直存在,不再开辟新空间
- 这个要从静态资源的储存方法地点来说,静态资源是随着类的加载而加载,在jvm进行类加载时,它会给静态资源分配一个固定分区而且这个固定分区在程序使用期间是一直存在的,直到类使用结束(程序终止)释放内存。
4、 全局唯一,全局共享
- 在Java内存中静态资源是储存在方法区中的静态资源区,而方法区是线程共享数据区,所以当中的静态资源也是可以被线程共享的。
5、 可以直接被类名调用
在之前的笔记中,有说到两种比较特殊的调用方法,其中一个就是类名.方法名这种调用方法的限制是只能使用static修饰的方法所在类的类名才可以。
而另外一种方法名直接调用方式,它也是需要static修饰,而且调用方式必须在同类中,即方法名直接调用这种方式必须在该方法的所在类中。
public class csdn_boke {
public static void main(String[] args) {
// TODO Auto-generated method stub
//类名.成员名调用方法和变量
text.yang();
System.out.println(text.name);
//本类中方法名直接调用
st();
}
//在本类中创建static修饰的方法
public static void st(){
System.out.println("在本类中可以直接方法名调用");
}
}
class text{
//static修饰变量
static String name = "yang";
//static修饰方法
static public void yang(){
System.out.println("这是被static修饰的,静态方法,通过类名调用");
}
}
6、 静态只能调用静态,非静态可以随意调用
- 静态方法里调用非静态资源——不行
class text{
//static修饰变量
static String name = "yang";
//成员变量,非静态变量
int a=10;
//static修饰方法
static public void yang(){
//到这里之后会发现出错了,在静态方法中不可调用非静态资源
System.out.println(a);
System.out.println("这是被static修饰的,静态方法,通过类名调用");
}
}
- 非静态方法调用静态资源——可以
class text{
//static修饰变量
static String name = "yang";
//成员变量,非静态变量
int a=10;
//static修饰方法
// static public void yang(){
// System.out.println(a);
// System.out.println("这是被static修饰的,静态方法,通过类名调用");
// }
public void yang2(){
//这里不会出错,在非静态方法中调用静态资源都是可以的。
System.out.println(name);
}
}
- 在以上两中调用类型中,非静态方法之所以能调用非静态资源,原因是因为静态资源的加载先于非静态资源,静态资源在类加载时就已经加载,而非静态资源只有在new类对象时才会加载。所以静态方法调用非静态资源是不可能的,因为都还没加载出来,所以不可能被使用。
7、 static不能和this或者super共用,因为有static时可能还没有对象
- 就是在static修饰中的方法中,不能使用this或则super,首先我们从this和super的作用来说,this的作用是调用本类中的成员,或则在构造方法中互相调用。super的作用是调用父类中的成员。那么在static修饰的方法中,static修饰的方法是和类一起加载的,而this和super的调用成员是new对象时加载的,所以在静态方法中使用this和super是无法识别的。
静态代码块
-
随着类的加载而加载,并且只被加载一次,一般用于项目的初始化
static{}
。所在的位置的类里代码外。 -
需要注意的几个点:
静态资源的加载是按照代码的先后顺序执行的。
静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问。
静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。 -
父类静态代码块,父类静态方法,子类静态代码块,子类静态方法的执行顺序:
public class csdn_boke {
public static void main(String[] args) {
// TODO Auto-generated method stub
new zi();
}
}
class fux{
static{
System.out.println("父类静态代码块");
}
{
System.out.println("父类构造代码块");
}
public fux(){
System.out.println("父类构造方法");
}
public static void fu1(){
System.out.println("父类静态方法");
}
}
class zi extends fux{
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类构造代码块");
}
public zi(){
System.out.println("子类构造方法");
}
public static void zi1(){
System.out.println("子类静态方法");
}
}
执行结果如下:这个就是父类和子类中静态代码块和构造代码块的执行顺序。