一、 概念

  • static是静态修饰符,主要是为了修饰成员变量,修饰行为方法,修饰代码块。

二、为什么要引入static?

  • 我们在定义一个类时,有时候需要在类的内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执行结束时会释放掉,但是 如果想将类中此变量的值保存至下一次调用, 是不可能的,所以要解决这个问题,最容易想到的方法是定义一个全局的变量,但在Java中没有全局变量。所以我们需要引入static。
class Person{
    private String name;
    private int age;
    private String sex;
    private int count;
    public Person() {
        // TODO Auto-generated constructor stub
        //如果写构造函数,系统自动生成构造函数,且构造函数是默认的。
        System.out.println("Person()");
        count=0;
    }

    public Person(String name, int age, String sex) {
        System.out.println("Person(String, int, String)");
        this.name = name;
        this.age = age;
        this.sex = sex;
        count++;
    }

    public int getPersonCount(){
        System.out.println();
        return count;
    }
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }

public class TestObjectDemo {

    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println(p1);
        Person p2 = new Person("zhang san", 20, "man");
        System.out.println(p2);
        Person p3 = new Person("li si", 20, "man");
        System.out.println(p3);
        Person p4 = new Person("li si", 20, "man");
        System.out.println(p4);
        System.out.println(Person.getPersonCount());
    }

}
  • 对于以上代码中count再次调用时是不会继续累加,所以每次count=1;为了解决这个问题我们用static修饰count,即private static int count。

三、java 静态成员变量

  • 按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量; 另一种是没有被 static 修饰的变量, 叫实例变量(普通变量)。
  • 两者的区别是:对于静态变量在内存中只有一个拷贝(节省内存) , JVM 只为静态分配一次内存, 在加载类的过程中完成静态变量的内存分配, 可用类名直接访问(方便) ,当然也可以通过对象来访问(但是这是不推荐的) ,静态成员都在方法区存着。对于实例变量, 没创建一个实例, 就会为实例变量分配一次内存, 实例变量可以在内存中有多个拷贝, 互不影响(灵活) ,在栈上存着。
  • 被 static 修饰的成员变量独立于该类的任何对象;也就是说, 它不依赖类特定的实例, 被类的所有实例共享。
  • 用 public 修饰的 static 成员变量本质是全局变量, 当声明它类的对象, 不生成 static 变量的副本, 而是类的所有实例共享同一个 static变量。
  • static 变量前可以有 private 修饰, 表示这个变量可以在类的静态代码块中, 或者
    类的其他静态成员方法中使用 ,但是不能在其他类中通过类名来直接引用,这一点很重要。
    四、java 静态成员方法
  • static 修饰的成员方法习惯上称为静态方法, 可以直接通过类名来访问。通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法声明为static的方法有以下几条限制: 它们仅能调用其他的static 方法。 它们只能访问static数据。
    它们不能以任何方式引用this 或super。
  • 普通成员方法必须得由对象来调用,而对象会产生this,从而可以由this来调用,所以静态方法不可以访问普通成员和普通方法,因为他们调用时必须对象来调用。但是普通成员方法可以调用和访问静态成员和方法。
    五、java 静态初始化块
    在介绍静态代码块之间我首先介绍一下实例初始化块
  • 实例初始化块:在方法或语句中出现的{}就称为实例初始化块。实例初始化块对象产生之前都要调用一次,且执行次序优先于类构造函数。
  • 静态初始化块:直接在类中定义且加static关键字的代码块称为{}静态初始化块。静态初始化块由JVM调用时,仅仅只是调用一次,是初始化静态成员,是对方法区进行初始化这个执行次序优先于实例初始化块,但是如果没有静态成员,不对静态成员初始化,那么就不会被调用。
class Person{

    private String name;
    private int age;
    private String sex;
    //静态初始化块
    static{
        System.out.println("static init block!");
        count = 0;
    }
    //实例(依赖于对象的成员)初始化块  对象产生之前都要调用一次
    {
        System.out.println("instance init block!");
        this.name = "default";
        this.age = 0;
        this.sex = "default";

    }




}