都說變數有七八種,到底誰是 Java 的親兒子

網上羅列了很多關於變數的理解,良莠不齊,不知道哪些是對的,哪些是錯的,所以筆者就這些部落格和自己的理解寫出這篇文章,如果有不對的地方,希望讀者能夠指正,感謝。

變數是我們經常用到的一種,我在剛學 Java 的時候,也經常被各種變數的概念折磨,當時並沒有細摳,但是我在寫一篇類似的文章中,想把變數作為一種小標題來簡述一下,但是發現,變數這個概念還是比較繁瑣的,本篇文章就來深入認識一下 Java 中這些變數的概念

變數匯總

所以,到底有哪些變數的概念呢?距今為止,目前已知的變數主要有

  • 實例變數
  • 全局變數
  • 靜態變數
  • 類變數
  • 局部變數
  • 成員變數
  • 常量

下面我們就採用各個擊破的方式來認識每個概念

實例變數

實例變數又被稱為Instance variables。不使用 static 關鍵字定義,並且在任何方法、構造方法、塊之外的變數都是實例變數。實例變數都是基於特定實例的,實例變數不會在實例之間共享,也就是說,每一個對象的實例都有自己的一個實例變數。下面是實例變數的一個例子

class Fruits {
  
  public String fruitName; // 具有公共訪問許可權的 fruitName;
  private int fruitNum;		 // 具有私有訪問許可權的 fruitNum;
  
}

你可以使用下面這種方式進行實例變數的調用

public class Fruits {

    public String fruitName;
    private int fruitNum;

    public static void main(String[] args) {
        Fruits fruits = new Fruits();
        fruits.fruitName = "strawberry";
        fruits.fruitNum = 100;
    }
}

如何識別實例變數

那麼我如何知道一個變數它是實例變數呢?下面是一些關於實例變數的定義規則

  • 實例變數可以使用四種訪問修飾符進行修飾:public、protected、default、private
  • 實例變數可以使用 transient、final 關鍵字進行修飾
  • 實例變數不可以使用 abstract、synchronized、strictfp、native、static關鍵字進行修飾

實例變數帶有默認值,也就是說,實例變數不用初始化就能使用。下面是常用實例變數的初始值

實例變數的特點

上面我們了解了實例變數的基本特徵和如何區分實例變數,下面我們來講一下實例變數的特點。

  • 實例變數的只能在類中聲明,但是在方法、構造函數或任何塊之外。

  • 當在為堆中對象分配空間時,將為每個實例變數分配一塊區域。

  • 實例變數只能通過創建對象來使用,當使用 new 關鍵字進行創建對象時,實例變數同時也被創建,當垃圾回收器回收對象時,實例變數也會被銷毀。

  • 實例變數可以使用訪問修飾符來修飾

  • 實例變數不用強制初始化,它有自己的默認值。

  • 每個對象都有自己的一個實例變數的副本,因此在一個對象中修改變數不會對其他對象中的實例變數造成影響

  • 實例變數只能通過創建對象引用來使用。

全局變數

全局變數又被稱為Global variables。如果你有其他語言的編程經驗,比如 C、C++ 的話,你會接觸到全局變數這個概念,你可以使用下面程式碼來創建全局變數

#include<stdio.h>

	// 全局變數
	int A;
	int B;

	int Add()
	{
		return A + B;
	}

但是在 Java 中,是不存在全局變數的。因為 Java 是一門面向對象的程式語言,所有的內容都是屬於類的一部分。Java 這麼做的原因是為了防止數據和類成員被其他程式的其他部分有意或者無意的修改。所以在 Java 中,使用 靜態變數 來起到全局訪問的目的。

靜態變數

靜態變數又被稱為Static variables。靜態變數的定義比較簡單,靜態變數是屬於該的變數,它是由 static 關鍵字來修飾的。static 修飾的變數屬於靜態變數,它只能定義在類的內部、方法的外部。

靜態變數的特點

  • 靜態變數只能使用 static 關鍵字進行修飾,它不能在方法中進行聲明,不論是靜態方法還是非靜態方法。

  • 靜態變數會在程式運行前進行初始化,並且只初始化一次。靜態變數會有一個初始化順序,我們後面說
  • 靜態變數的所有實例共享同一個副本。也就是說,靜態變數只有一個,它不會隨著對象實例的創建而進行副本拷貝
  • 靜態變數可以通過類名.變數名 進行訪問,並且不需要創建任何對象就能訪問。
public class Fruits {

    public String fruitName;
    private int fruitNum;
    static String fruitType;

    public static void main(String[] args) {
        Fruits.fruitType = "apple"; // 類名.變數名
        System.out.println(fruitType);
    }
}
  • 可以在非靜態方法 中使用靜態變數

類變數

類變數又被稱為 Class variables在 Java 中,類變數就是靜態變數,它們都用 static 關鍵字進行修飾,所以,如果你再聽到說靜態變數的時候,它也就是類變數。

局部變數

還有一種說法,說 Java 中只有類變數、實例變數和局部變數。這麼分也沒有問題,可能有人會問到,你把成員變數和常量放在哪了?別著急我們後面會說

先來說一下什麼是局部變數

局部變數又稱為 Local variables。它指的是在方法中、構造器中或者塊程式碼中定義的變數。局部變數的生命周期隨方法、構造器、程式碼塊的執行完畢而銷毀。

不管上面的一些變數概念如何變換、局部變數都站如松,坐如鐘,行如風,卧如弓,從容應對各種不同文章的比較。真是一個省事的變數。

那麼這麼好的東西我們可要仔細研究一下其特點是啥

  • 根據定義可知,局部變數定義在方法、構造器或者程式碼塊中;
  • 然後局部變數的生命周期隨方法、構造器、程式碼塊的執行完畢而銷毀;
  • 局部變數不能使用訪問修飾符,例如如下程式碼

  • 局部變數僅在方法的聲明、構造函數或者塊內可見,局部變數只能在調用這些方法、構造函數或者塊的內部使用

  • 局部變數沒有默認值,所以局部變數應該在第一次使用或者聲明的時候就應該初始化完成

成員變數

什麼?成員變數在 Java 中就是實例變數?這個結論對嗎?

常量

驗證過程

為了驗證這個結論,我們求助於了 stackoverflow 網站

我們搜索 java member variable and instance variable 就幫我們定為到了這個標題

大致意思是:什麼是成員變數?成員變數和實例變數是否相同呢?我們下面有個回答

第一句就給出,實例變數和類變數都稱為成員變數,然後給出了 JDK 官網手冊對變數的定義。意思是在 Java 中,只有三中類型的變數

  • 定義在類中的成員變數 — 被稱為屬性
  • 定義在方法(包含構造方法)或者塊程式碼中的變數 — 被稱為局部變數
  • 定義在方法定義中的變數 — 被稱為參數

嗯。。。或許還不是很好解決我們的問題,我帶著問題再次求助 JDK 官網手冊,又看到了關於 Variables 的定義

意思是在 Java 中,只有下面幾種類型的變數(別扯別的了,莫非你比官網還靠譜?)

  • 實例變數(非靜態屬性) :大致意思就是說

非靜態屬性也就被稱為實例變數,因為它們的值是相對於每個實例來說的。換句話說,對於每個對象來講,實例變數的值都是唯一的;

  • 類變數(靜態屬性):類變數就是使用 static 修飾符聲明的欄位,這就會告訴編譯器:無論該類被實例化了多少次,該變數只存在一個副本。另外,可以添加關鍵字 final 來表示常量

  • 局部變數:沒有特殊的關鍵字將制定的變數聲明為局部變數、確定其聲明的完全取決於聲明變數的位置。

  • 參數:想一下我們平常用到最多的方法是什麼方法?當然是 main 方法啊,main 方法是怎麼定義的?

public static void main(String[] args) {}

其中的 args 是不是就是 String 的數組的變數,我們也稱其為參數,所以參數也沒有關鍵字進行聲明,標識其為參數也只是取決於其聲明位置。

bilibili

所以
我寫了一篇文章為了給你講清楚,現在你應該知道 Java 中到底有哪些變數了吧。

如果你用 static 來定義變數,只能是類變數、或者說靜態變數、而且其定義位置只能在類中,方法或程式碼塊外,變數的副本只有一個。

如果你不用 static 來聲明變數,那麼就會有三種變數的叫法

  • 定義在構造方法、程式碼塊、方法的變數被稱為實例變數,實例變數的副本數量和實例的數量一樣。
  • 定義在方法、構造方法、程式碼塊的變數被稱為局部變數;
  • 定義在方法參數的變數被稱為參數。

也就是下面程式碼所描述的這樣

public class VariablesInJava {

	int instanceVariable; // 實例變數

	static String staticVariable; // 類變數

	public void method() {
    
		String localVariable = "localVariable"; // 局部變數
		System.out.println(localVariable);
	}

	public static void main(String args[]) {} //參數
}

Tags: