Java中的static关键字的作用及使用

static的作用

1.修饰属性
2.修饰方法
3.修饰代码块
4.修饰类(本文不说哦)
重点看前三种


一.修饰属性

  在定义一个类时,只是在描述某类事物的特征和行为,并没有产生具体的数据。只有通过new关键字创建该类的实例化对象后,系统才会为每个对象分配内存空间,存储各自的数据。
  有时候,开发人员会希望某些特定的数据在内存中只有一份,而且能够被一个类的所有实例化对象所共享。这时候就可以用static来修饰属性。此时被static修饰的属性属于类而不属于对象,被所有对象共享。

访问方式

类名.属性名

我们来看个代码更容易理解一些:

class Test2 {
    public int a;
    public static int count;
}

 class Main{
     public static void main(String[] args) {
         Test2  t1=new Test2();
         t1.a++;             //非静态属性用(引用.变量名)访问
         Test2.count++;      //静态变量用(类名.变量名)访问
         System.out.println(t1.a);
         System.out.println(Test2.count);
         System.out.println("=============");
         Test2 t2=new Test2();
         t2.a++;
         Test2.count++;
         System.out.println(t2.a);
         System.out.println(Test2.count);
     }
}

//打印结果
1
1
=============
1
2


  上述代码中a就是普通的成员变量,count是静态变量,a随着对象实例化而被创建,是在堆中,t1为引用,保存着堆里变量a的地址,每当new一个对象系统就会分配一个空间给a,且初始值都为0,a++打印1,所以两次结果都为1。

  而count被修饰为静态,它被保存在JVM的方法区里,被所有对象共享,所以每次访问到的都是同一块内存,所以第一次count++值为1,第二次给1的基础上加1就打印2。

注意:static关键字只能用来修饰成员变量,不能用于修饰局部变量,否则编译会报错。

public class Student{
   public void study(){
      static int num=10;       //编译会报错
   }
}




二.修饰方法

  通过对类和对象学习已经知道,如果想要使用类中的方法,就需要先将这个类实例化,在实际开发中,开发人员有时候会希望在不创建对象的情况下就可以调用某个方法,这种情况就可以使用静态方法。
  定义静态方法,只需要在类中的方法前加上static关键词即可。
  静态方法属于类,而不属于类的对象;可以直接调用静态方法,而无需创建类的实例;静态方法可以访问静态数据成员,并可以更改静态数据成员的值。


访问方式

1.类名.方法名
2.实例对象名.方法名

观察下列代码:

class Test2{
     public int a;
     public static int count;

     public static void change(){
         count=100;   //可以访问静态数据成员
         //a=10;      error   静态方法不可以访问非静态数据成员
     }
 }

 class  Main{
     public static void main(String[] args) {
         Test2.change();    //用类名去访问
         System.out.println(Test2.count);
          Test2 t2=new Test2();   //用实例化对象去访问
         System.out.println(t2.count);
     }
 }
 

//打印结果
100
100


为什么main方法要用static来修饰?
  首先,如果不用static来修饰,那么如果要调用main方法就要先new一个对象,通过对象的引用来调用main方法,而如果要new对象就得先进入main方法才可以执行new这个动作,这样下来两者互相矛盾,所以将main方法用static来修饰,不用创建对象,用类名就可以直接访问。


注意
  ①静态方法和实例无关,而是和类相关
  ②静态方法不能直接使用非静态数据成员或调用非静态方法
  ③this,super两个关键字不能在静态上下文中使用(this是当前实例的引用,super是当前实例父类实例的引用)



三.修饰代码块

 字段的初始化方式有:
1.就地初始化
2.使用构造方法初始化
3.使用代码块初始化

那么什么是代码块呢?
 就是使用{}定义的一段代码
而根据代码块定义的位置及关键字,又可以分为以下四种
①普通代码块 ②构造块 ③静态块 ④同步代码块(这里不说哦)


1.普通代码块
 定义在方法内部的代码块(用法较少见)

public class Test {
    public static void main(String[] args) {
        {  //直接使用{}定义   普通方法块
            int x=10;
            System.out.println("x1="+x);
        }
        int x=100;
        System.out.println("x2="+x);
    }
}


//打印结果
x1=10
x2=100


2.构造代码块和静态代码块

  构造块:定义在类中的代码块(不加修饰符)也叫实例代码块。在类的内部,方法的外部,和方法同级,用来初始化类的实例数据成员。实例代码块优先于构造方法执行
  静态代码块:使用static定义的代码块。一般用于初始化静态成员属性

观察下图代码:

class Person{
    private String name;
    private int age;
    public static int count = 10;

    //静态代码块-》初始化 静态的数据成员
    static {
        count = 9999999;
        System.out.println("static{}");
    }

    //实例代码块 --》 初始化类的实例数据成员
    {
        this.name = "caocao";
        this.age = 99;
        System.out.println("instance{}");
    }

    public Person() {
        System.out.println("Person()");
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    public void sleep() {
        System.out.println("睡觉");
    }

}
public class Test {
    public static void main(String[] args) {
        new Person().sleep();  //调用无参构造方法
        new Person().sleep();
    }
}


//打印结果
static{}
instance{}
Person()
睡觉
instance{}
Person()
睡觉
8888



  上图代码中我们new了两个对象,观察打印结果可以发现静态代码块不管生成多少个对象,其只会执行一次,并且是最先执行。静态代码块执行完毕后,实例代码块执行,再然后是构造方法,最后才是普通方法的执行。

你可能感兴趣的:(JavaSE)