Java非訪問修飾符

Java提供了許多非訪問修飾符來實現許多其他功能。

  • static修飾符用於創建類方法和變量。
  • final修飾符用於完成類,方法和變量的實現。
  • abstract修飾符用於創建抽象類和方法。
  • synchronizedvolatile修飾符,用於線程。

下面來逐個瞭解和學習這些非訪問修飾符。

1. static修飾符

1.1. 靜態變量

static關鍵字用於創建獨立於類實例的變量。無論類的實例數有多少個,都只存在一個靜態變量副本。靜態變量也稱爲類變量。局部變量不能聲明爲static

1.2. 靜態方法

static關鍵字用於創建獨立於類實例的方法。
靜態方法不能使用作爲類的對象的實例變量,靜態方法也叫作類方法。靜態方法從參數中獲取所有數據並從這些參數計算某些內容,而不引用變量。可以使用類名後跟一個點(.)以及變量或方法的名稱來訪問類變量或方法。

示例

  • static修飾符用於創建類方法和變量,如下例所示 -
public class InstanceCounter {

   private static int numInstances = 0;

   protected static int getCount() {
      return numInstances;
   }

   private static void addInstance() {
      numInstances++;
   }

   InstanceCounter() {
      InstanceCounter.addInstance();
   }

   public static void main(String[] arguments) {
      System.out.println("Starting with " + InstanceCounter.getCount() + " instances");

      for (int i = 0; i < 500; ++i) {
         new InstanceCounter();
      }
      System.out.println("Created " + InstanceCounter.getCount() + " instances");
   }
}

執行上面示例代碼,得到以下結果:

Started with 0 instances
Created 500 instances

2. final修飾符

2.1. final變量

final變量只能顯式地初始化一次,聲明爲final的引用變量永遠不能重新分配以引用不同的對象。但是,可以更改對象內的數據。 因此,可以更改對象的狀態,但不能更改引用。
對於變量,final修飾符通常與static一起使用,以使常量成爲類變量。

示例

public class Test {
   final int value = 10;

   // 以下是聲明常量的示例:
   public static final int BOXWIDTH = 6;
   static final String TITLE = "Manager";

   public void changeValue() {
      value = 12;   // 會出錯,不能重新賦值
   }
}

2.2. final方法

任何子類都不能覆蓋final方法。 如前所述,final修飾符可防止在子類中修改方法。

聲明final方法的主要目的是不讓其它人改變方法的內容。

示例
可以在類聲明中使用final修飾符聲明方法,如下例所示 -

public class Test {
   public final void changeName() {
      // 方法主體
   }
}

2.3. final類

使用聲明爲final的類的主要目的是防止類被子類化。 如果一個類被標記爲final,那麼這個類不能被其它類繼承。

示例

public final class Test {
   // body of class
}

3. abstract飾符

3.1. 抽象類

抽象(abstract)類不能實例化。如果一個類聲明爲抽象(abstract),那麼唯一的目的是擴展該類。

一個類不能是同時是abstractfinal(因爲final類不能被擴展)。 如果一個類包含抽象方法,那麼該類應該被聲明爲abstract。 否則,將拋出編譯錯誤。

抽象類可以包含抽象方法以及普通方法。

示例

abstract class Caravan {
   private double price;
   private String model;
   private String year;
   public void getYear(String y){};// 這是一個普通方法
   public abstract void goFast();   // 這是一個抽象方法
   public abstract void changeColor();// 這是一個抽象方法
}

3.2. 抽象方法
抽象方法是在沒有任何實現的情況下聲明的方法。 方法體(實現)由子類提供。 抽象方法永遠不會是最終的或嚴格的。

擴展抽象類的任何類都必須實現超類的所有抽象方法,除非子類也是抽象類。

如果一個類包含一個或多個抽象方法,那麼該類必須聲明爲abstract。 抽象類不需要包含抽象方法。

抽象方法以分號結尾。 示例:public abstract sample();

示例

public abstract class SuperClass {
   abstract void m();   // 抽象方法
}

class SubClass extends SuperClass {
   // 實現抽象方法
   void m() {
      // 實現代碼.........
   }
}

4. synchronized修飾符

synchronized關鍵字用於指示一次只能訪問一個方法的方法。synchronized修飾符可以應用於四個訪問級別修飾符中的任何一個。

示例

public synchronized void showDetails() {
   .......
}

5. transient修飾符

實例變量標記爲transient,表示JVM在序列化包含它的對象時跳過特定變量。

此修飾符包含在創建變量的語句中,位於變量的類或數據類型之前。

示例

public transient int limit = 55;   // will not persist
public int b;   // will persist

6. volatile修飾符

volatile修飾符用於讓JVM知道訪問變量的線程必須始終將其自己的變量私有副本與內存中的主副本合併。

訪問volatile變量會同步主內存中變量的所有緩存複製。 volatile只能應用於實例變量,類型爲privatevolatile對象引用可以爲null

示例

public class MyRunnable implements Runnable {
   private volatile boolean active;

   public void run() {
      active = true;
      while (active) {   // line 1
         // some code here
      }
   }

   public void stop() {
      active = false;   // line 2
   }
}

通常,在一個線程(使用Runnable開始的線程)中調用run(),並從另一個線程調用stop()。 如果在第1行中使用了active的緩存值,那麼當在第2行中將active設置爲false時,循環可能不會停止。