它是Java里面的修饰词,被static修饰的类、方法、变量等等都会在类加载的时候自动在方法区分配一次,此后便不在创建。
这说明了被static修饰之后有且只有一个存在,而且调用的时候并不需要对象(也可以用但是不提倡),可以直接用类名来调用。
被stati修饰之后,将不会属于任何类的任何一个对象,但是可以被类的所有对象共有。
static的五种用法
可以自己去尝试来验证我说的到底是否正确,印象会更加深刻
static不能被用来修饰普通的类,但是可以被修饰内部类。
被修饰的内部不可以调用任何非静态类方法和成员变量,但是非静态方 法可以调用静态内部类。
static修饰成员变量的时候就会在类加载的时候存放于方法区,所有类的实例对象共享。
static不会改变访问修饰权限
跟修饰成员变量差不多。静态方法不可以使用this、super等关键字,也不能直接调用非静态方法
格式static{ }
说到了静态块就不得不说下,jvm的加载机制,来通过一个例子观察:
public class StaticTest {
MyPrint my=new MyPrint();
static{
System.out.println("StaticTest静态块输出");
}
public StaticTest(){
System.out.println("StaticTest构造方法输出");
}
public static void main(String[] args) {
StaticTest aa= new MyTest();
}
}
class MyTest extends StaticTest{
MyPrint my=new MyPrint();
static{
System.out.println("MyTest静态块输出");
}
public MyTest(){
System.out.println("MyTest构造方法输出");
}
}
class MyPrint{
static{
System.out.println("MyPrint静态块输出");
}
public MyPrint(){
System.out.println("MyPrint构造方法输出");
}
}
大家可以猜猜输出是什么。
输出
StaticTest静态块输出
MyTest静态块输出
MyPrint静态块输出
MyPrint构造方法输出
StaticTest构造方法输出
MyPrint构造方法输出
MyTest构造方法输出
为什么这样呢?来看下jvm加载做的事情
1.jvm会去找main所在的类,并加载。在加载的时候遇到静态块会优先加载,所以输出 StaticTest静态块输出。
2.然后会执行main方法,发现需要实例MyTest类,所以会去加载此类发现有父类,会去加载父类,因为静态块只加载一次所以不会再有输出。
3.发现父类已经加载过,继续往下走静态方法优先加载 输出 :MyTest静态块输出。
4.加载完毕开始实例化发现成员变量就开始加载实例成员变量,发现静态块输出 MyPrint静态块输出。
5.继续实例化成员变量类发现构造方法输出:MyPrint构造方法输出。
6.成员变量实例化完毕开始走MyTest构造方法,因为有隐形的super(),
所以开始运行父类的构造方法又发现隐藏的super()一直到Object类,然后开始向下运行回到StaticTest构造方法,运行完毕输出:StaticTest构造方法输出
7.然后实例化父类的成员变量输出:MyPrint构造方法输出(静态块只运行一次所有没有上面那句了)
8.最后回到本类完成构造方法输出 MyTest构造方法输出。
import static java.xx.xx;
这样导包后可以直接使用静态方法和变量,而不用再去用类名点,但是如果引入两个相同方法名不同包的静态方法,去使用会报错。
以上就是本人理解的static关键词的使用,有错可以一起讨论