介紹
Java 是一種靜態類型的編程語言。這意味著當您創建一個變量時,您必須同時指定其數據類型,即它存儲的信息類型。這與動態類型的語言形成對比,例如PHP。使用動態類型的語言時,您無需指定變量的數據類型,這可能看起來很輕鬆。
然而,瞭解數據類型並適當使用它們可以使開發人員優化其代碼,因為每種數據類型都具有特定的資源需求。而且,如果您指定一種數據類型並嘗試存儲不同類型的數據,例如錯誤地進行,則無法編譯代碼。因此,使用靜態類型的語言,您可以在進行任何測試之前就檢測到錯誤。
Java 有兩種 數據類型: 原始 和 引用(也稱為 非原始)。在本教程中,您將使用 變量 來存儲和使用 Java 程序中的信息,以了解 Java 中一些常用的數據類型。這並不是對所有數據類型的詳盡概述,但這個指南將幫助您熟悉在 Java 中有哪些選擇。
先決條件
要按照本教程操作,您需要:
-
一個可以執行 Java 程式以便跟隨示例的環境。要在本機設置此功能,您需要以下內容:
- 在您的機器上安裝 Java(版本 11 或以上),並使用 Java 開發套件(JDK)提供的編譯器。對於 Ubuntu 和 Debian,請按照我們教程中 選項 1 的步驟進行操作,參見我們的教程,如何在 Ubuntu 22.04 上使用 Apt 安裝 Java。對於其他操作系統,包括 Mac 和 Windows,請參閱 Java 安裝的下載選項。
- 編譯和運行代碼示例,本教程使用 Java Shell,這是一個從命令行運行的 讀取-評估-打印(REPL)。要開始使用 JShell,請查閱 JShell 簡介 指南。
-
熟悉Java和面向對象編程,您可以在我們的教程如何在Java中編寫您的第一個程序中找到。
原始類型
Java的原始類型是Java中最簡單和最基本的數據類型。它們表示原始值,如數字和字符。最常用的原始數據類型包括int
(整數)、boolean
(布爾值)和char
(字符)。你可以在官方的Java數據類型文檔中找到其餘類型。
整數
整數既可以是負數也可以是正數。在Java中,你會使用int
來存儲它們。int
可以容納足夠大的數字,適用於大多數情況:從-2,147,483,648
到2,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
的內置方法println
將theAnswer
打印到控制台。這是測試變量是否按預期聲明的最簡單方法。
要查看此代碼的運行情況,請使用 Java Shell 工具。安裝 Java 後,在本地計算機上打開終端或命令提示符,然後輸入jshell
:
- jshell
您的輸出將類似於以下內容:
Output| Welcome to JShell -- Version 11.0.16
| For an introduction type: /help intro
jshell>
您可以將此教程中的代碼示例粘貼到控制台中。完成後,您可以通過輸入/exit
退出jshell
。
要聲明並使用int
,請將以下行粘貼到jshell
控制台中:
- int theAnswer = 42;
- System.out.println("The answer to all questions is " + theAnswer);
您將看到以下輸出:
OutputtheAnswer ==> 42
The answer to all questions is 42
此輸出確認您正確將int
變量theAnswer
設置為 42(theAnswer ==> 42
)。您還成功地將theAnswer
傳遞給一個方法並且該方法產生了預期的變量值。
布林
布林值可以是true
或false
。在Java中,您將使用boolean
來存儲它們。例如,讓我們創建一個boolean
變量來定義Java是否有趣:
boolean isJavaFun = true;
您將變量isJavaFun
定義為true
。另一個boolean
值是false
。
使用上面的變量,您可以像這樣打印句子Java is fun: true
:
- boolean isJavaFun = true;
- System.out.println("Java is fun: " + isJavaFun);
在jshell
中運行這些行將產生以下輸出:
OutputisJavaFun ==> 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
方法,如下所示:
- String hello = new String("Hello");
- System.out.println(hello);
在jshell
中運行這些代碼將產生以下輸出:
Outputhello ==> "Hello"
Hello
這次輸出確認hello
變數設置為Hello
。之後,同樣的Hello
被打印到新行,確認println()
方法已處理它。
包裝類
在前一節中,您使用了經常使用的String
參考類型。其他常見的參考類型是所謂的基本類型的包裝類。一個包裝類包裝或包含基本數據,因此得名。所有基本類型都有相應的包裝類,以下是一些例子:
Integer
:用於包裝int
值。Character
:用於包裝char
值。Boolean
:用於包裝boolean
值。
這些包裹存在是為了將簡單的基本值升級為強大的對象。每個包裹都有與其設計用於存儲的值相關的 ready-to-use 方法。
舉例來說,你將探索 Integer
。在前一節中,你使用 new
關鍵字創建了一個 String
對象。然而,一些類提供,甚至鼓勵使用從它們那裡獲取對象的特殊方法,而 Integer
就是其中之一。在 Integer
的情況下,使用特殊方法主要是為了資源優化,但在其他情況下,可能是為了簡化複雜對象的構建。
在以下示例中,你使用 valueOf
方法 創建一個名為 theAnswer
,值為 42
的 Integer
變量:
- Integer theAnswer = Integer.valueOf(42);
- System.out.println(theAnswer);
在 jshell
中,你將獲得以下輸出:
OutputtheAnswer ==> 42
42
通過調用 Integer
方法 valueOf(42)
,你指示 Java 為你提供一個具有此值的對象。在幕後,Java 將檢查是否已經存在具有該值的對象。如果有,該對象將與 theAnswer
變量關聯。如果沒有,將為 theAnswer
變量創建一個新對象。
出於性能原因,許多內置類提供此類方法,強烈建議使用,如果不是強制性的。在 Integer
的情況下,你仍然可以使用 new
關鍵字創建對象,但將收到一個不推薦的警告。
除了String
和包裝類型之外,還有其他一些有用的內置引用類型,您可以在java.lang 包摘要中找到它們。要完全理解這些更高級的引用類型中的一些,需要額外的解釋或先備知識。這就是為什麼我們將在我們下一個Java系列教程中涵蓋其中一些的原因。
字面值
字面值代表可以直接在代碼中使用的固定值,因此可以將它們分配給基本類型和引用類型。有幾種類型的字面值,可以分類如下。
基本類型字面值
您已經在基本類型的部分中使用了一些字面值。對於每個基本類型,都有一個字面值,例如我們的例子中的那些:42
,'a'
和true
。例如,像42
這樣的整數是整數字面值。同樣,像'a'
這樣的字符是字符字面值,true
和false
是布爾字面值。
原始类型字面值也可以用于创建引用类型的值。在创建一个Integer
对象的代码中使用了int
字面值,代码为Integer.valueOf(42)
。还有一种简写方式,您可以直接赋值,如下所示:
Integer theAnswer = 42;
42
是一个整数字面值,就像任何整数一样,您可以直接将其赋值给theAnswer
变量,而无需任何其他语句。这种声明Integer
的方式很常见,因为它很方便。
这种简写方法也适用于其他原始类型字面值及其对应的引用类型,例如Boolean
:
Boolean isFun = true;
true
是字面值,直接赋值给类型为Boolean
的isFun
变量。还有一个false
字面值,您可以以相同的方式赋值。
字符串字面值
还有一个特殊的字面值用于String
引用类型,它的特点是用双引号括起来。在这个例子中,它是"Hello, World!"
:
String helloWorld = "Hello, World!";
使用字面值更简单、更短,这就是为什么很多程序员喜欢它的原因。然而,您仍然可以像在引用类型部分中已经做过的那样,使用新的String
对象声明一个String
变量。
Null 字面值
還有一個重要的字面值:null
,代表著值的缺失或對象的不存在。Null
允許你創建一個引用類型並將其指向 null
而不是指向一個對象。null
可以用於所有引用類型,但不能用於任何原始類型。
- String initiallyNullString = null;
- System.out.println("The class name is: " + initiallyNullString.getClass());
關於 null
字面值有一個注意事項:你可以使用它來聲明變量,但在重新分配一個適當的非空值之前,你不能使用這些變量。如果你嘗試使用一個具有 null
值的引用類型變量,你將會得到一個錯誤。以下是一個例子:
OutputinitiallyNullString ==> null
| Exception java.lang.NullPointerException
| at (#4:1)
當你嘗試在 jshell
中運行這段代碼時,你將會看到類似以下的錯誤:
根據你的操作系統和 Java 版本,你的輸出可能會有所不同。
注意: 為了簡化起見,我們將 java.lang.NullPointerException
稱為錯誤,即使它在技術上是一個異常。有關異常和錯誤的更多信息,請查看教程:Java 中的異常處理。
為了解決錯誤,您必須重新指定initiallyNullString
的值,如下所示:
- String initiallyNullString = null;
- initiallyNullString = "not null any longer";
- System.out.println("The class name is: " + initiallyNullString.getClass());
修復後的代碼將打印以下輸出:
OutputinitiallyNullString ==> 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
的示例來看一下:
- var hello = "Hello";
- System.out.println(hello);
您使用var
關鍵字聲明變量hello
,以指示Java檢測其數據類型。然後,您以通常的方式將其打印到控制台上以確認它按預期工作:
Ouputhello ==> "Hello"
Hello
只要您的Java安裝(更具體地說,是JDK)版本在10以上,此示例將正常工作。var
關鍵字不支持舊版本。
類型推斷發生在編譯過程中 – 也就是說,當您編譯代碼時。編譯過程將純文本源代碼轉換為機器代碼並應用各種優化,包括類型推斷。這確保了對於類型推斷的變量有足夠的系統內存可用。因此,編譯後運行的機器代碼是完全優化的,就好像您手動指定了所有數據類型一樣。
在這個例子中,var
關鍵字之所以有效是因為該變量是局部的,而 var
數據類型僅適用於局部變量。局部變量定義在方法內部並且只能在方法內部訪問,這就是為什麼它們被稱為“局部”的原因。
為了顯示var
僅可用於局部變量,請嘗試將其放在主方法之外,如下所示:
- public class Hello {
- var hello = "Hello";
- public static void main(String[] args) {
- // example code
- }
- }
當您在 jshell
中粘貼上述代碼時,您將會得到以下錯誤:
Output| Error:
| 'var' is not allowed here
| var hello = "Hello";
| ^-^
var
不允許在這裡使用,因為 hello
處於方法外部並且不再被認為是局部的。因此,對於非局部變量,類型推斷不起作用,因為上下文無法可靠地用於檢測數據類型。
雖然使用var
可能具有挑戰性並且並非必需,但您可能會遇到它,因此了解它是有用的。
保留關鍵字
當在Java中聲明變量時,有一個更重要的規則需要知道。有一些保留關鍵字不能用於變量名稱。例如,您不能聲明一個類型為`int`的原始變量並將其命名為`new`,就像這樣:
- 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