今天在重写java的过程中,学到static这块,就简单对其做个总结和归纳。
static 是静态的含义,在java中,可以用来修饰成员变量、成员方法以及代码块。
被static修饰的普通成员变量就是静态变量,普通的成员变量是随着对象的创建而加载,而静态变量只随着类加载而加载一次,且当静态变量的权限大于private时,可以直接通过类名.变量名进行调用。
以下通过定义一个员工类进行说明:
//这是一个员工类
public class EmployeeStatic {
//这是一个普通成员变量
public String name;
//这是一个静态变量
public static String company;
}
public static void main(String[] args) {
EmployeeStatic02 e = new EmployeeStatic02();
//对于普通成员变量,则需要先创建一个员工对象,再对其进行调用以及赋值
e.name = "张三";
EmployeeStatic02 e2 = new EmployeeStatic02();
e2.name = "里斯";
//直接通过类名.变量名,对静态变量进行赋值以及调用
EmployeeStatic02.company = "AWM公司";
System.out.println("员工姓名:" + e.name + " 公司:" + EmployeeStatic02.company);
System.out.println("员工姓名:" + e2.name + " 公司:" + EmployeeStatic02.company);
System.out.println("----------------");
//直接通过 员工1.变量名,对静态变量进行赋值以及调用
e.company = "阿里";
System.out.println("员工姓名:" + e.name + " 公司:" + e.company);
System.out.println("员工姓名:" + e2.name + " 公司:" + e2.company);
System.out.println("----------------");
//直接通过 员工2.变量名,对静态变量进行赋值以及调用
e2.company = "腾讯";
System.out.println("员工姓名:" + e.name + " 公司:" + e.company);
System.out.println("员工姓名:" + e2.name + " 公司:" + e2.company);
}
运行结果:
员工姓名:张三 公司:AWM公司
员工姓名:里斯 公司:AWM公司
——————
员工姓名:张三 公司:阿里
员工姓名:里斯 公司:阿里
———————
员工姓名:张三 公司:腾讯
员工姓名:里斯 公司:腾讯
可以看出,无论是通过类名.静态变量进行调用赋值,还是通过对象.静态变量进行调用赋值,所以对其实现的实例对象的的静态变量值都会发生改变。
拓展:
注1:访问权限:public>protected>default(一般省略)>private。
注2: static + final所修饰的变量为全局变量(相当于常量),再定义时对其进行赋值,且值不可改变
eg:public static final NUM = 1;
被static修改的方法是静态方法,和静态变量一样,普通成员方法的调用需要依赖于对象,而静态方法可以直接通过调用类进行使用,权限大于private时,可以直接通过类名.变量名进行调用。
以下也通过一个实例对其进行说明:
首先先定义俩个方法,一个普通成员方法,一个静态方法
public class StaticMethod {
public void method1() {
System.out.println("这是一个普通方法");
}
public static void methodStatic() {
System.out.println("这是一个静态方法");
}
}
public static void main(String[] args) {
StaticMethod s = new StaticMethod();
//对象名.成员方法 进行调用
s.method1();
// 类名.静态方法、类目.静态变量的方式进行调用
StaticMethod.methodStatic();
}
输出结果:
这是一个普通方法
这是一个静态方法
以上就是对静态方法的简单调用
拓展:
在普通的成员方法中,可以使用成员变量和静态变量,而在静态方法中,只可以使用静态变量,不能使用成员变量
public class StaticDemo4 {
public int num = 10;
public static int staticNum = 20;
public void method1() {
//普通成员方法中调用普通成员变量
System.out.println(num);
//普通成员方法中调用静态变量
System.out.println(staticNum);
}
public static void methodStatic() {
//静态方法中调用静态变量
System.out.println(staticNum);
//静态方法中调用普通成员变量(会报错)
//System.out.println(num); //错误写法,静态方法中不允许调用普通成员变量
}
}
因为在一个方法的加载过程中,会先加载static的变量和方法,再进行调用普通的成员变量和方法,首先加载了静态变量,然后再加载静态方法,加载过程中,静态变量已经加载成功,所以可以调用成功,但普通成员变量还没创建加载,所以不能调用。
static代码块在类中可以有多个,且位置不固定,没有先后顺序。但在类的加载中,只会执行一次,且是最先执行的。如果有多个,则是根据出现的先后顺序进行依次执行。
public class StaticMethodDemo02 {
static {
System.out.println("这是第一个静态代码块");
}
public static void main(String[] args) {
System.out.println("这是一个主方法");
}
static {
System.out.println("这是第二个静态代码块");
}
}
执行结果:
这是第一个静态代码块
这是第二个静态代码块
这是一个主方法
由执行结果可以看出以上结论的正确性。
拓展:
带有继承的静态代码块,构造代码块以及类的构造方法直接加载顺序又是如何呢?
可以通过以下实例得出结论
public class FU {
public FU() {
System.out.println("FU中的构造方法");
}
static {
System.out.println("FU方法中的静态代码块");
}
{
System.out.println("FU方法中构造代码块");
}
}
public class Zi extends FU {
int num = 10;
static int staticnum = 20;
public Zi() {
System.out.println("Zi中的构造方法"+"..."+num);
}
static {
System.out.println("Zi方法中的静态代码块"+"..."+staticnum);
// System.out.println("Zi方法中的静态代码块"+"..."+num); // 报错
}
{
System.out.println("Zi方法中构造代码块"+"..."+num);
}
public static void main(String[] args)
{
new Zi();
}
}
运行结果:
FU方法中的静态代码块
Zi方法中的静态代码块…20
FU方法中构造代码块
FU中的构造方法
Zi方法中构造代码块…10
Zi中的构造方法…10
结论1:在带有继承的静态代码块,构造代码块以及类的构造方法直接加载顺序,父类中静态代码块>子类中静态代码块>父类中的构造代码块>父类中构造方法>子类中构造代码块>子类中构造方法
结论2:根据子类三行代码的执行顺序,可以得到非继承关系中,静态变量>静态代码块>成员变量>构造代码块(成员方法)>构造方法
以上就是小枫我现如今对static这块的掌握内容,日后如果有其他更深层次的学习,再进行补充。
如果其他小伙伴对这块有不一样或者新的见解,欢迎评论互相学习。