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
来源: http://www.bubuko.com/infodetail-3039448.html