static关键字的作用主要是实现某个方法或属性与类相关而不是与对象相关,主要有4种使用情况:成员变量,成员方法,代码块和内部类。
1.static关键字修饰成员变量
package test; public class staticAttributeTest { /* * 局部变量:局部变量是写在类中具体的方法里的; * 成员变量:是在类中定义的变量,包括用static修饰的静态变量和不用static修饰的实例变量; * * 实例变量(全局变量):在类中定义的没有static修饰的变量,实例变量只有实例化对象之后才可以使用,每当实例化一个对象, * * 会创建一个副本并初始化,各个对象中的实例变量的修改互不影响; * static: * 1.实现某个方法或属性与类关联而不是与对象关联,这样就可以在不创建对象的情况下通过类来直接调用方法或使用类的属性; * staticInt是被类拥有的,任意一个对象修改它的值,都会引起该值的变化。而nonStaticInt为实例变量,只有创建对象之后才可以调用, * 为该对象自己的值,只能对象修改自己的实例变量的值;不同的对象对该值的修改互不影响; * */ public static int staticInt=0; public int nonStaticInt=0; public static void main(String[] args){ staticAttributeTest t=new staticAttributeTest(); System.out.println(t.staticInt); //0 System.out.println(staticAttributeTest.staticInt); //0 System.out.println(t.nonStaticInt); //0 t.staticInt++; t.nonStaticInt++; staticAttributeTest t1=new staticAttributeTest(); staticAttributeTest t2=new staticAttributeTest(); //静态变量只有一个,被类拥有,存储在方法区中,所有对象共享这个静态变量; System.out.println(t1.staticInt); //1 System.out.println(t2.staticInt); //1 System.out.println(staticAttributeTest.staticInt); //1 //实例变量是与具体对象相关的 /* * 所有的实例变量、引用变量的地址都存在栈内存中,对象本身及对象的数据成员都存在堆内存中 * */ System.out.println(t1.nonStaticInt); //0 t1.nonStaticInt++; System.out.println(t1.nonStaticInt); //1 System.out.println(t2.nonStaticInt); //0 } }
2.static成员方法
static修饰的方法是类的方法,不需要创建对象就可以直接调用,而非static方法是对象的方法,只有对象被创建出来后才可以被调用。static方法不能调用非static方法,也不能访问非static类型的变量(非static的只有创建对象才可以调用和访问,static都没有对象)。
static方法中也不能使用this和super关键字,在java中使用this来引用当前对象,使用super引用父类的成分。
this关键字的作用:https://www.cnblogs.com/bluetree2/p/10784375.html
super关键字的作用:https://www.cnblogs.com/bluetree2/p/10784962.html
3.static代码块
static代码块不在任何一个方法内,可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
package test; class FatherClass { public int value; public void f() { value=100; System.out.println("父类的value属性值="+value); } public FatherClass(){ System.out.println("FatherClass constructor"); } } class ChildClass extends FatherClass { /** * 子类除了继承父类所具有的value属性外,自己又另外声明了一个value属性, * 也就是说,此时的子类拥有两个value属性。 */ public ChildClass(){ super(); System.out.println("ChildClass constructor"); } public int value; /** * 在子类ChildClass里面重写了从父类继承下来的f()方法里面的实现,即重写了f()方法的方法体。 */ public void f() { //使用super作为父类对象的引用对象来调用父类对象里面的f()方法 //这个value是子类自己定义的那个value,不是从父类继承下来的那个value value=200; super.f(); //父类的value属性值=100 System.out.println("子类的value属性值="+value); //子类的value属性值=200 //打印出来的是子类自定义的那个value的值,这个值是200 System.out.println(value); //200 System.out.println(super.value); //100 } } public class SuperKeyTest { static{ System.out.println("static block1"); } public static void main(String[] args) { ChildClass cc = new ChildClass(); cc.f(); } static{ System.out.println("static block2"); } }
执行结果:
static block1 static block2 FatherClass constructor ChildClass constructor 父类的value属性值=100 子类的value属性值=200 200 100