[Java] Java 中static关键字的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/FightFightFight/article/details/81677003

1.静态变量和静态方法

一般而言,类中的每个属性、方法都和该类的实例相关联,因为在通过new得到类的实例后,才会为该实例分配特定的内存空间,如:


class Student {

    int age;
    String name;
}


public class TestStatic {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Student stu1 = new Student();
        Student stu2 = new Student();
        stu1.name = "zhangsan";
        stu2.name = "lisi";

        System.out.println("stu1.name="+stu1.name+",stu2.name="+stu2.name);
    }

}
输出:
stu1.name=zhangsan,stu2.name=lisi

现在有如下两种情景:

  • 1.将类中某一个属性存储在特定的存储空间中,且不随着类的对象的创建而创建,也就是说,不管有多少个对象,共享同一个属性和值(同一份数据);

  • 2.即使不创建类的对象,也能够通过类名调用类的方法;

通过static关键字就能够实现上述场景,如:

public class Student {

    static String mSchool = "HighSchool";
    int age;
    String name;

    static String printSchool(){
        return mSchool;
    }
}


public class TestStatic {

    public static void main(String[] args) {

        Student stu1 = new Student();
        Student stu2 = new Student();
        stu1.name = "zhangsan";
        stu2.name = "lisi";

        System.out.println("stu1.mSchool="+stu1.mSchool+",stu2.mSchool="+stu2.mSchool+",Student.mSchool="+Student.printSchool());
    }
}
输出:
stu1.mSchool=HighSchool,stu2.mSchool=HighSchool,Student.mSchool=HighSchool

特点

  • 1.static方法中不能使用this.因为this表示当前的对象,而static修饰的属性和方法独立于类的对象而存在。

  • 2.static方法中不能使用非static变量.一是由于非static的变量是依赖于对象的,而static方法独立于对象而存在;二是因为静态方法和静态变量在类的字节码文件加载到JVM时就已经存在,而非静态方法和变量只有在获取实例后才会存在;

  • 3.非static方法中可以使用static变量.因为静态变量在类的加载时就初始化,所以肯定在非静态变量和费静态方法之前就存在,因此可以使用。

  • 4.不能修饰局部变量.因为局部变量的作用域为定义该变量的方法体,方法执行完毕后将会被销毁,而static修饰的变量作用域为整个类,两者矛盾,因此语法规则static关键字不能修饰局部变量。

静态方法也称作类方法,非静态方法也称作实例方法。

2.静态代码块

使用static修饰的代码块叫作静态代码块,静态代码块经常用于初始化类的静态变量,其格式如下:

static {
    i = 1;
    str = "zhangsan";
    // ......
}

当类被加载到JVM时,静态代码块被执行,且执行一次。
那何时类将会被加载到JVM呢?

  • 1.首次生成这个类的一个对象时;
  • 2.首次访问这个类的静态数据成员时。

3.静态变量的初始化步骤

java中永远是先初始化静态变量,然后才会初始化非静态变量,其初始化顺序可总结为:

静态代码块 > 构造代码块 > 构造方法 > 局部代码块,

在《java编程思想》P95中,给出了一个关于静态变量初始化非常经典的例子,这里引用一下:

package com.jyq.test;

public class Bowl {

    public Bowl(int i) {
        System.out.println("Bowl("+i+")");
    }
    public void f1(int i) {
        System.out.println("f1("+i+")");
    }

}

package com.jyq.test;

public class Table {

    static Bowl bowl1 = new Bowl(1);
    Table(){
        System.out.println("Table()");
        bowl2.f1(1);
    }
    public void f2(int i) {
        System.out.println("f2("+i+")");
    }
    static Bowl bowl2 = new Bowl(2);

}


package com.jyq.test;

public class Cupboard {

    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    public Cupboard() {
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }
    public void f3(int i) {
        System.out.println("f3("+i+")");    
    }
    static Bowl bowl5 = new Bowl(5);

}


package com.jyq.test;

public class StaticInitialization {

    public static void main(String[] args) {
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();

}

执行结果:

Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)

参考资料

《java编程思想》

猜你喜欢

转载自blog.csdn.net/FightFightFight/article/details/81677003
今日推荐