理解Java中的數據類型

作者選擇了自由開源基金作為為捐助寫作計畫的一部分。

介紹

Java 是一種靜態類型的編程語言。這意味著當您創建一個變量時,您必須同時指定其數據類型,即它存儲的信息類型。這與動態類型的語言形成對比,例如PHP。使用動態類型的語言時,您無需指定變量的數據類型,這可能看起來很輕鬆。

然而,瞭解數據類型並適當使用它們可以使開發人員優化其代碼,因為每種數據類型都具有特定的資源需求。而且,如果您指定一種數據類型並嘗試存儲不同類型的數據,例如錯誤地進行,則無法編譯代碼。因此,使用靜態類型的語言,您可以在進行任何測試之前就檢測到錯誤。

Java 有兩種 數據類型原始引用(也稱為 非原始)。在本教程中,您將使用 變量 來存儲和使用 Java 程序中的信息,以了解 Java 中一些常用的數據類型。這並不是對所有數據類型的詳盡概述,但這個指南將幫助您熟悉在 Java 中有哪些選擇。

先決條件

要按照本教程操作,您需要:

原始類型

Java的原始類型是Java中最簡單和最基本的數據類型。它們表示原始值,如數字和字符。最常用的原始數據類型包括int(整數)、boolean(布爾值)和char(字符)。你可以在官方的Java數據類型文檔中找到其餘類型。

整數

整數既可以是負數也可以是正數。在Java中,你會使用int來存儲它們。int可以容納足夠大的數字,適用於大多數情況:從-2,147,483,6482,147,483,647

讓我們看一下在示例中如何使用int

int theAnswer = 42;

原始類型始終以小寫字母開頭(int)。Java語法規則要求你首先指定數據類型(int),然後是其名稱(theAnswer)。之後,你用等號(=)給變量賦值42

無論數據類型如何,您都可以直接指定其名稱而無需添加任何特殊字符。這是因為 Java 可以將其識別為變量。

注意:此教程中變量theAnswer的名稱以及所有其他變量均以駝峰命名法編寫。即使沒有嚴格的要求使用它,但這是 Java 中被接受的命名慣例。

聲明變量後,您可以在方法中引用它,如下所示:

int theAnswer = 42;
System.out.println("The answer to all questions is " + theAnswer);

在第二行,您使用來自包System.out的內置方法printlntheAnswer打印到控制台。這是測試變量是否按預期聲明的最簡單方法。

要查看此代碼的運行情況,請使用 Java Shell 工具。安裝 Java 後,在本地計算機上打開終端或命令提示符,然後輸入jshell

  1. jshell

您的輸出將類似於以下內容:

Output
| Welcome to JShell -- Version 11.0.16 | For an introduction type: /help intro jshell>

您可以將此教程中的代碼示例粘貼到控制台中。完成後,您可以通過輸入/exit退出jshell

要聲明並使用int,請將以下行粘貼到jshell控制台中:

  1. int theAnswer = 42;
  2. System.out.println("The answer to all questions is " + theAnswer);

您將看到以下輸出:

Output
theAnswer ==> 42 The answer to all questions is 42

此輸出確認您正確將int變量theAnswer設置為 42(theAnswer ==> 42)。您還成功地將theAnswer傳遞給一個方法並且該方法產生了預期的變量值。

布林

布林值可以是truefalse。在Java中,您將使用boolean來存儲它們。例如,讓我們創建一個boolean變量來定義Java是否有趣:

boolean isJavaFun = true;

您將變量isJavaFun定義為true。另一個boolean值是false

使用上面的變量,您可以像這樣打印句子Java is fun: true

  1. boolean isJavaFun = true;
  2. System.out.println("Java is fun: " + isJavaFun);

jshell中運行這些行將產生以下輸出:

Output
isJavaFun ==> true Java is fun: true

int示例類似,方法println將打印括號中提供的參數。加號(+)將字符串“Java is fun:”與變量isJavaFun連接或組合在一起,因此實際上,它只是一個參數——字符串Java is fun: true

字符

要存儲單個字母數字字符,您將使用char。例如:

char firstLetter = 'a';

請注意,字母a被單引號包圍。單引號僅用於char值。雙引號用於字符串,稍後您將了解到。

char 看起來不像是一個特別有用的類型,因為你不太可能需要一個變量分配給單個字符。然而,char 被用作字符串類的基礎,比如 String,它們基本上是一組 char 值的集合。

正如您在本節中所看到的,基本類型變量的聲明和使用是直接的,因為它們表示諸如整數之類的簡單值。這些值可以立即使用,不需要額外的操作,比如創建對象、調用方法等。

參考類型

在這個系列的第一個教程中,如何在Java中編寫您的第一個程序,您學到了Java代碼是以類組織的,這些類被用作創建對象的模板。當這些對象被分配給變量時,您正在指向或引用這些對象。在這些情況下,這些變量被分類為參考類型。這些變量也被稱為非原始類型,因為原始類型變量不能指向對象。

物件之所以強大,是因為它們具有高級屬性,並且在觸發其方法時能夠起作用。然而,如果沒有指向它們的變數,這些物件將無法訪問並且實際上無法使用。這就是為什麼引用類型變數對於Java和整個面向對象編程至關重要。

註: 引用類型指向從類創建的物件。為了避免混淆,在下面的示例中,引用類型和創建的物件將是相同的類。

然而,在複雜的程序中,這種情況很少見。在Java中,一個介面是對特定行為的一組要求,這些要求可以由一個或多個類滿足。滿足介面要求的類被稱為實現該介面。因此,在複雜的程序中,通常會聲明一個具有介面引用類型的變數。這樣,您就可以指定您的變數應該展示的行為,而不必將其綁定到該行為的具體實現。這使您可以輕鬆地更改您的變數指向的實現,而無需更改變數的使用方式。這個複雜的概念是關於繼承多態性的更高級話題的一部分,將在我們的Java系列教程中進行獨立介紹。

儘管只有幾種基本類型,但參考類型幾乎是無限的,因為類(和接口)的數量沒有限制,每個類代表一個參考類型。Java 中有許多內置類提供基本功能。最常用的一些可以在核心 java.lang 套件中找到。您將在本節中回顧其中一些。

String

String 類代表組成字符串的字符組合。要聲明一個 String 或任何其他參考類型變量,首先指定其類型,然後是其名稱。然後,使用等號為其分配一個值。到目前為止,這與使用基本類型類似。但是,參考類型指向對象,因此如果尚未創建對象,則必須創建對象。這是一個例子:

String hello = new String("Hello");

hello 是具有參考類型 String 的變量名稱。將其分配給新的 String 對象。新的 String 對象使用 new 關鍵字與類名一起創建 – 在這種情況下為 String。類 String 以大寫字母開頭。按照慣例,所有類和因此參考類型都以大寫字母開頭。

每個類別都有一個特殊的方法,稱為建構子,用於創建新物件。您可以通過在類別名稱末尾加上括號(())來調用這個建構子。建構子可能接受參數,就像上面的例子中,參數"Hello"應用於String的建構子中。

為確認hello變數的行為是否符合預期,可以將其再次傳遞給println方法,如下所示:

  1. String hello = new String("Hello");
  2. System.out.println(hello);

jshell中運行這些代碼將產生以下輸出:

Output
hello ==> "Hello" Hello

這次輸出確認hello變數設置為Hello。之後,同樣的Hello被打印到新行,確認println()方法已處理它。

包裝類

在前一節中,您使用了經常使用的String參考類型。其他常見的參考類型是所謂的基本類型的包裝類。一個包裝類包裝或包含基本數據,因此得名。所有基本類型都有相應的包裝類,以下是一些例子:

  • Integer:用於包裝int值。
  • Character:用於包裝char值。
  • Boolean:用於包裝boolean值。

這些包裹存在是為了將簡單的基本值升級為強大的對象。每個包裹都有與其設計用於存儲的值相關的 ready-to-use 方法。

舉例來說,你將探索 Integer。在前一節中,你使用 new 關鍵字創建了一個 String 對象。然而,一些類提供,甚至鼓勵使用從它們那裡獲取對象的特殊方法,而 Integer 就是其中之一。在 Integer 的情況下,使用特殊方法主要是為了資源優化,但在其他情況下,可能是為了簡化複雜對象的構建。

在以下示例中,你使用 valueOf 方法 創建一個名為 theAnswer,值為 42Integer 變量:

  1. Integer theAnswer = Integer.valueOf(42);
  2. System.out.println(theAnswer);

jshell 中,你將獲得以下輸出:

Output
theAnswer ==> 42 42

通過調用 Integer 方法 valueOf(42),你指示 Java 為你提供一個具有此值的對象。在幕後,Java 將檢查是否已經存在具有該值的對象。如果有,該對象將與 theAnswer 變量關聯。如果沒有,將為 theAnswer 變量創建一個新對象。

出於性能原因,許多內置類提供此類方法,強烈建議使用,如果不是強制性的。在 Integer 的情況下,你仍然可以使用 new 關鍵字創建對象,但將收到一個不推薦的警告。

除了String和包裝類型之外,還有其他一些有用的內置引用類型,您可以在java.lang 包摘要中找到它們。要完全理解這些更高級的引用類型中的一些,需要額外的解釋或先備知識。這就是為什麼我們將在我們下一個Java系列教程中涵蓋其中一些的原因。

字面值

字面值代表可以直接在代碼中使用的固定值,因此可以將它們分配給基本類型和引用類型。有幾種類型的字面值,可以分類如下。

基本類型字面值

您已經在基本類型的部分中使用了一些字面值。對於每個基本類型,都有一個字面值,例如我們的例子中的那些:42'a'true。例如,像42這樣的整數是整數字面值。同樣,像'a'這樣的字符是字符字面值,truefalse是布爾字面值。

原始类型字面值也可以用于创建引用类型的值。在创建一个Integer对象的代码中使用了int字面值,代码为Integer.valueOf(42)。还有一种简写方式,您可以直接赋值,如下所示:

Integer theAnswer = 42;

42是一个整数字面值,就像任何整数一样,您可以直接将其赋值给theAnswer变量,而无需任何其他语句。这种声明Integer的方式很常见,因为它很方便。

这种简写方法也适用于其他原始类型字面值及其对应的引用类型,例如Boolean

Boolean isFun = true;

true是字面值,直接赋值给类型为BooleanisFun变量。还有一个false字面值,您可以以相同的方式赋值。

字符串字面值

还有一个特殊的字面值用于String引用类型,它的特点是用双引号括起来。在这个例子中,它是"Hello, World!"

String helloWorld = "Hello, World!";

使用字面值更简单、更短,这就是为什么很多程序员喜欢它的原因。然而,您仍然可以像在引用类型部分中已经做过的那样,使用新的String对象声明一个String变量。

Null 字面值

還有一個重要的字面值:null,代表著值的缺失或對象的不存在。Null 允許你創建一個引用類型並將其指向 null 而不是指向一個對象。null 可以用於所有引用類型,但不能用於任何原始類型。

  1. String initiallyNullString = null;
  2. System.out.println("The class name is: " + initiallyNullString.getClass());

關於 null 字面值有一個注意事項:你可以使用它來聲明變量,但在重新分配一個適當的非空值之前,你不能使用這些變量。如果你嘗試使用一個具有 null 值的引用類型變量,你將會得到一個錯誤。以下是一個例子:

Output
initiallyNullString ==> null | Exception java.lang.NullPointerException | at (#4:1)

當你嘗試在 jshell 中運行這段代碼時,你將會看到類似以下的錯誤:

根據你的操作系統和 Java 版本,你的輸出可能會有所不同。

注意: 為了簡化起見,我們將 java.lang.NullPointerException 稱為錯誤,即使它在技術上是一個異常。有關異常和錯誤的更多信息,請查看教程:Java 中的異常處理

為了解決錯誤,您必須重新指定initiallyNullString的值,如下所示:

  1. String initiallyNullString = null;
  2. initiallyNullString = "not null any longer";
  3. System.out.println("The class name is: " + initiallyNullString.getClass());

修復後的代碼將打印以下輸出:

Output
initiallyNullString ==> null initiallyNullString ==> "not null any longer" The class name is: class java.lang.String

上面的輸出顯示了initiallyNullString如何首先為null,然後變為包含"not null any longer"的新String對象。接下來,當在實例化的對象上調用getClass()方法時,您將獲得java.lang.String,其中String是類名,java.lang是其包。最後,將打印出一條完整且有意義的消息:"The class name is: class java.lang.String"

這種null值聲明在舊代碼中更常見。它們被用來首先創建一個變量,然後稍後為其分配其真實值,通常通過一些確定後者的邏輯。但是,自Java版本8以來,引入了一種新的引用類型,稱為Optional,在以前使用null的情況下更適用。

本地變量類型推斷

直到現在,您一直在使用Java中的一些常見數據類型來定義變量。但是,Java 10引入了一個新功能,稱為本地變量類型推斷,它允許您在新變量前面使用關鍵字var。使用此功能,Java將從本地上下文中推斷(也就是自動猜測)數據類型。類型推斷是有爭議的,因為它與先前解釋的變量定義的冗長性形成對比。這種功能的優點和缺點是有爭議的,但事實是,其他靜態類型的語言,如C++,支持類型推斷。

無論如何,類型推斷無法完全取代數據類型的使用,因為它僅適用於本地變量,即方法內的變量。讓我們通過一個使用var的示例來看一下:

  1. var hello = "Hello";
  2. System.out.println(hello);

您使用var關鍵字聲明變量hello,以指示Java檢測其數據類型。然後,您以通常的方式將其打印到控制台上以確認它按預期工作:

Ouput
hello ==> "Hello" Hello

只要您的Java安裝(更具體地說,是JDK)版本在10以上,此示例將正常工作。var關鍵字不支持舊版本。

類型推斷發生在編譯過程中 – 也就是說,當您編譯代碼時。編譯過程將純文本源代碼轉換為機器代碼並應用各種優化,包括類型推斷。這確保了對於類型推斷的變量有足夠的系統內存可用。因此,編譯後運行的機器代碼是完全優化的,就好像您手動指定了所有數據類型一樣。

在這個例子中,var 關鍵字之所以有效是因為該變量是局部的,而 var 數據類型僅適用於局部變量。局部變量定義在方法內部並且只能在方法內部訪問,這就是為什麼它們被稱為“局部”的原因。

為了顯示var僅可用於局部變量,請嘗試將其放在主方法之外,如下所示:

  1. public class Hello {
  2. var hello = "Hello";
  3. public static void main(String[] args) {
  4. // example code
  5. }
  6. }

當您在 jshell 中粘貼上述代碼時,您將會得到以下錯誤:

Output
| Error: | 'var' is not allowed here | var hello = "Hello"; | ^-^

var 不允許在這裡使用,因為 hello 處於方法外部並且不再被認為是局部的。因此,對於非局部變量,類型推斷不起作用,因為上下文無法可靠地用於檢測數據類型。

雖然使用var可能具有挑戰性並且並非必需,但您可能會遇到它,因此了解它是有用的。

保留關鍵字

當在Java中聲明變量時,有一個更重要的規則需要知道。有一些保留關鍵字不能用於變量名稱。例如,您不能聲明一個類型為`int`的原始變量並將其命名為`new`,就像這樣:

  1. int new = 1;

如果您嘗試這個例子,您將會得到編譯錯誤,因為`new`是一個保留關鍵字。

Output
| Error: | '.class' expected | int new = 1; | ^ | Error: | <identifier> expected | int new = 1; | ^ | Error: | '(' or '[' expected | int new = 1; | ^ | Error: | unexpected type | required: value | found: class | int new = 1; | ^--^ | Error: | missing return statement | int new = 1; | ^----------^

關鍵字`new`用於創建新對象,Java不希望它出現在這個位置。在上一個輸出的錯誤列表中,第一部分是最重要的:

Output
| Error: | '.class' expected | int new = 1; | ^

錯誤`’.class’ expected`意味著當您使用`new`關鍵字時,Java期望後面跟著一個類。在這一點上,Java無法解釋這個語句,其餘的錯誤隨之而來。

其餘的保留關鍵字,例如`abstract`、`continue`、`default`、`for`和`break`,在Java中也有特定的含義,不能用於變量名稱。保留關鍵字的完整列表可以在Java語言關鍵字頁面上找到。即使您不記得所有的保留關鍵字,您也可以使用編譯錯誤來識別問題。

結論

在這個教程中,您學到了Java中的原始數據類型和引用數據類型,這是一個複雜但至關重要的主題。花些時間來練習它,多次閱讀示例。嘗試更改一些數據類型和值。注意何時會引發錯誤,何時不會,以發展對代碼成功執行的感覺。

有關Java的更多信息,請查看我們的如何在Java中編碼系列。

Source:
https://www.digitalocean.com/community/tutorials/understanding-data-types-in-java