有时我们希望定义一个类成员,使其作为该类的公共成员,所有实例都共享该成员变量,此时需要使用static关键字。


 

static 修饰变量

类的成员变量中,用static修饰的变量称为静态变量或者类变量,而没有用static修饰的变量则是普通变量。

对于普通成员变量,每创建一个该类的实例就会创建该成员变量的一个拷贝,分配一次内存。由于成员变量是和类的实例绑定的,所以需要通过对象名进行访问,而不能直接通过类名对它进行访问。

而对于静态变量在内存中只有一份,Java虚拟机(JVM)只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配。由于静态变量属于类,与类的实例无关,因而可以直接通过类名访问这类变量。

我们来修改Post类,增加一个计数器,记录Post对象的个数。

1 public class Post {
 2 
 3     private String title;
 4     private String content;
 5     
 6     public static int count = 0;
 7     
 8     public Post(){
 9         count++;
10     }
11     ...
12 }

 

titlecontent是我们之前定义的实例成员变量,每个Post实例都独立的拥有titlecontent属性,此时修改这两个字段的值,对其他Post实例不会有影响。

我们再来看count,我们将其声明为static,表明count是个静态变量。当我们修改count的值时,所有实例的count值都会改变。每当我们实例化一个Post对象,我们使count值+1,此时,我们可以直接通过Post.count 得到一共有多少Post实例。


static修饰方法

public static int getCount(){
        return count;
    }

这里我们是通过类名.方法的方式访问静态方法getCount()的。

声明成static的方法有几条限制:

  • 仅能调用其他的static方法。
  • 只能访问static数据。
  • 不能以任何方式引用thissuper

静态方法可以直接通过类名调用,任何的该类的实例也都可以调用它的静态方法,因此静态方法中不能用thissuper关键字。(大家共享的 不纯在你的我的  所以不能用this super)

在一个static方法中引用任何实例变量都是非法的。


 

静态代码块

类似于静态变量和静态方法,有static修饰的代码块称为静态代码块。

它独立于类成员,可以有多个,JVM加载类的时候会执行这些静态代码块,如果static代码块有多个,JVM则会按照它们在类中出现的顺序依次执行它们,且每个代码块只能执行一次。我们可以利用静态代码块可以对一些static变量进行赋值。

如果我们的Post数量是从数据库中取得的,此时如果简单的给count赋值为1明显是不对的,此时我们可以通过静态代码段在类加载进来时执行获取count值的代码块:

1 public class Post {
 2         
 3     private String title;
 4     private String content;
 5     
 6     private static int count = 0;
 7     
 8     static {
 9         count = 100; //这里假设100是从数据库中获取Post的数量
10     }
11     
12     public Post(){
13         count++;
14     }
15     
16     public static int getCount(){
17         return count;
18     }
19         ...
20 }