可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立。然而在某些时候,希望该类所有的对象共享同一个成员。此时就是 static 发挥其功效的地方,即存在以下结论:
-
static修饰的成员变量和方法,从属于类
-
普通变量和方法从属于对象
-
静态方法不能调用非静态成员,编译会报错
Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。
1.静态变量
public class staticStudy {
static String var = "staticvar";
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("通过类名访问静态变量: "+staticStudy.var);
//通过对象名访问
staticStudy objectname = new staticStudy();
System.out.println("通过对象名访问静态变量: "+objectname.var);
//静态方法直接调用静态变量
System.out.println("静态方法直接访问静态变量:"+var);
//使用对象名访问修改静态变量的值
objectname.var = "staticvarnew;
}
}
2.静态方法
static方法也成为静态方法,最常见的静态方法就是main(),由于静态方法不依赖于任何对象就可以直接访问,因此对于静态方法来说,是没有this的,因为不依附于任何对象,既然都没有对象,就谈不上this了,并且由于此特性,在静态方法中不能访问类的非静态成员变量和非静态方法,因为非静态成员变量和非静态方法都必须依赖于具体的对象才能被调用。
静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法和静态成员变量。
2.1 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。
静态方法中访问非静态变量会报错。那如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。
public class staticStudy {
static String varStatic = "staticvar";
String varGeneral = "vargeneral";
public static void print() {
System.out.println("静态方法访问静态变量:"+varStatic);
staticStudy object = new staticStudy();
System.out.println("静态访问访问非静态变量:"+object.varGeneral);
}
}
2.2 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量
public class staticStudy {
static String varStatic = "staticvar";
String varGeneral = "vargeneral";
public static void print() {
System.out.println("静态方法访问静态变量:"+varStatic);
staticStudy object = new staticStudy();
System.out.println("静态访问访问非静态变量:"+object.varGeneral);
}
public void show() {
System.out.println("普通方法访问普通变量:"+varGeneral);
System.out.println("普通方法访问静态变量:"+varStatic);
}
}
2.3 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法
public class staticStudy {
static String varStatic = "staticvar";
String varGeneral = "vargeneral";
public static void print() {
System.out.println("静态方法访问静态变量:"+varStatic);
staticStudy object = new staticStudy();
System.out.println("静态访问访问非静态变量:"+object.varGeneral);
}
public void show() {
System.out.println("普通方法访问普通变量:"+varGeneral);
System.out.println("普通方法访问静态变量:"+varStatic);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("通过类名访问静态变量: "+staticStudy.varStatic);
//通过对象名访问
staticStudy objectname = new staticStudy();
System.out.println("通过对象名访问静态变量: "+objectname.varStatic);
//静态方法通过对象访问非静态方法
objectname.show();
//静态方法直接调用静态变量
System.out.println("静态方法直接访问静态变量:"+varStatic);
}
3 static 使用之静态初始化块
package com.imooc;
public class staticStudy {
static String varStatic;
String varGeneral1,varGeneral2;
public staticStudy() {
varGeneral1 = "structInitialGeneral";
System.out.println("通过构造函数为普通变量赋值");
}
{
//普通变量初始化
varGeneral2 = "blockInitialGeneral";
System.out.println("通过初始化块为普通变量赋值");
}
{
//静态变量初始化
varStatic = "blockstaticvar";
System.out.println("通过初始化块为静态变量赋值");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
staticStudy objectVar = new staticStudy();
System.out.println("varGeneral1:"+objectVar.varGeneral1);
System.out.println("varGeneral2:"+objectVar.varGeneral2);
System.out.println("varStatic:"+varStatic);
staticStudy objectVar2 = new staticStudy();
}
}
通过输出结果,我们可以看到,程序运行时普通初始化块最先被执行,然后执行静态初始化块,最后才执行构造方法。