跳轉到內容

基本資料型別

100% developed
來自 Wikibooks,開放世界中的開放書籍

瀏覽 語言基礎 主題:v  d  e )


基本型別是 Java 語言中最基本的資料型別。共有 8 種:booleanbytecharshortintlongfloatdouble。這些型別是 Java 中資料操作的基礎。這些型別只服務於一個目的 - 包含純粹的、簡單的某種型別的值。因為這些資料型別在 Java 型別系統中預設定義,所以它們附帶了許多預定義的操作。你無法為這些基本型別定義新的操作。在 Java 型別系統中,還有三種基本型別的類別。

  • 數值基本型別:shortintlongfloatdouble。這些基本資料型別只儲存數值資料。與這些資料型別相關的操作是簡單算術(加、減等)或比較(大於、等於等)。
  • 文字基本型別:bytechar。這些基本資料型別儲存字元(可以是Unicode 字母表甚至數字)。與這些型別相關的操作是文字操作(比較兩個單詞、連線字元構成單詞等)。但是,bytechar 也可以支援算術運算。
  • 布林和空基本型別:booleannull

所有基本型別都有固定大小。因此,基本型別的值範圍有限。較小的基本型別(byte)可以包含的值比更大的型別(long)少。

類別 型別 大小(位) 最小值 最大值 精度 示例
整數 byte 8 -128 127 從 +127 到 -128 byte b = 65;
char 16 0 216-1 所有 Unicode 字元[1] char c = 'A';
char c = 65;
short 16 -215 215-1 從 +32,767 到 -32,768 short s = 65;
int 32 -231 231-1 從 +2,147,483,647 到 -2,147,483,648 int i = 65;
long 64 -263 263-1 從 +9,223,372,036,854,775,807 到 -9,223,372,036,854,775,808 long l = 65L;
浮點型 float 32 2-149 (2-2-23)·2127 從 3.402,823,5 E+38 到 1.4 E-45 float f = 65f;
double 64 2-1074 (2-2-52)·21023 從 1.797,693,134,862,315,7 E+308 到 4.9 E-324 double d = 65.55;
其他 boolean -- -- -- false, true boolean b = true;
void -- -- -- -- --

整數基本型別會靜默溢位

Example 程式碼部分 3.52:幾個運算子。
int i = Integer.MAX_VALUE;
System.out.println(i);
i = i + 1;
System.out.println(i);
System.out.println(Integer.MIN_VALUE);
Computer code 程式碼部分 3.52 的控制檯
2147483647
-2147483648
-2147483648

由於 Java 是強型別語言,因此不能將浮點數(帶小數點的數字)賦值給整型變數

Warning 程式碼部分 3.53:將浮點數設定為 int(整型)型別的值。
int age;
age = 10.5;

基本型別應透過適當的值設定。基本型別可以用字面量初始化。大多數字面量都是基本型別的值,除了字串字面量,它們是 String 類的例項。

計算機科學中的數字

[編輯 | 編輯原始碼]

程式設計可能不再像以前那樣只是處理大量的數字,既不平凡也不無聊。然而,如今任何程式語言(更不用說 Java)中編寫的程式碼的大部分都在痴迷地處理數字,無論是生成巨大的素數[2],還是僅僅計算你的踏板車排放的成本。1965 年,雙子座五號 太空任務險些因程式設計錯誤而發生致命事故[3]。1979 年,一個計算機程式高估了五個核反應堆抵抗地震的能力;這些工廠暫時關閉[4]。這兩個程式設計錯誤都有一個共同點:錯誤發生時正在計算的主題資料是數值的。從過去的經驗來看,Java 帶來了針對數值資料的改進的型別檢查,並非常重視正確識別其不同型別。在程式設計方面,你必須認識到數值資料的意義。

數字使用二進位制系統儲存在記憶體中。記憶體就像一個單元格網格

                               

每個單元格可以包含一個二進位制數字(簡稱為),也就是說,零或一

 0   1   1   0   0   1   0   1 

實際上,每個單元格確實包含一個二進位制數字,因為一位大約相當於1,而記憶體中的空單元格表示0。單個二進位制數字只能儲存兩種可能的值:零或一。

記憶體狀態 給出
                             0  0
                             1  1

多個位組合在一起可以儲存多個排列 - 2 位可以儲存 4 種可能的值,3 位可以儲存 8 種,依此類推。例如,8 位可以儲存的最大數字(二進位制中的11111111)在十進位制系統中是255。因此,從 0 到 255 的數字可以放入 8 位中。

記憶體狀態 給出
 0   0   0   0   0   0   0   0  0
 0   0   0   0   0   0   0   1  1
 0   0   0   0   0   0   1   0  2
 0   0   0   0   0   0   1   1  3

...
...
 1   1   1   1   1   1   1   1  255

一切都很好,但這樣我們只能儲存正數(或無符號整數)。它們被稱為無符號整數。無符號整數是所有為正的整數值,不歸因於負值。出於這個原因,我們會要求 8 位中的一個位儲存有關數字符號(正數或負數)的資訊。這使我們只剩下 7 位來實際計算一個數字。這 7 位可以儲存的最大數字(1111111)在十進位制系統中是127

正數

記憶體狀態 給出
 0   0   0   0   0   0   0   0  0
 0   0   0   0   0   0   0   1  1
 0   0   0   0   0   0   1   0  2
 0   0   0   0   0   0   1   1  3

...

...
...
 0   1   1   1   1   1   1   1  127


負數

記憶體狀態 給出
 1   0   0   0   0   0   0   0  -128
 1   0   0   0   0   0   0   1  -127
 1   0   0   0   0   0   1   0  -126
 1   0   0   0   0   0   1   1  -125

...

...
...
 1   1   1   1   1   1   1   1  -1


總之,使用這種方法,8 位可以儲存從-128127(包括零)的數字 - 共 256 個數字。有人可能會認為,這不算太糟糕。與無符號整數相反的是有符號整數,它能夠儲存正值和負值。

但是,較大的數字怎麼辦?你需要更多的位來儲存更大的數字。這就是 Java 的數值型別發揮作用的地方。Java 有多種數值型別 - 它們的尺寸取決於參與的位數。

在 Java 中,數字使用專門用於儲存數值資料的型別進行處理。但在深入研究這些型別之前,我們必須首先確定一些概念。就像你在高中(甚至小學)做的那樣,Java 中的數字被放置在明顯不同的組和系統中。你可能已經知道,數字系統包括整數(0、1、2 ... ∞);負整數(0、-1、-2 ... -∞)甚至實數有理數圓周率值、¾、0.333~ 等)。Java 只是傾向於將這些數字分成兩組,整數(-∞ ... 0 ... ∞)和浮點數(任何帶有小數點或分數表示的數字)。目前,我們只關注整數值,因為它們更容易理解和使用。

Java 中的整型

[編輯 | 編輯原始碼]

透過我們迄今為止學到的知識,我們將識別出在 Java 中可以建立和操作的不同型別有符號整數。以下是最基本數值型別:整數的表格。正如我們之前討論過的,Java 中用於整數的資料型別既可以容納正值也可以容納負值,因此它們是 **有符號數值型別**。數值型別的大小以位為單位,它決定了該型別的最小值和最大值。如有疑問,您始終可以計算這些值。

讓我們看看這些新發現的 Java 中基本整數型別的知識如何融入整體。假設您想對一年中的天數進行數值操作——所有 365 天。您會使用哪種型別?由於資料型別 `byte` 僅能達到 127,您是否願意冒著賦予它大於其允許最大值的風險?此類決定可能會讓您免受可能因程式設計程式碼而產生的可怕錯誤的困擾。對於此類數值操作,更明智的選擇可能是 `short`。現在,為什麼他們不能只製作一種資料型別來儲存所有型別的數字呢?讓我們來探討一下原因。

當您告訴程式您需要使用一個整數,比如甚至是一個 `byte` 時,Java 程式會在記憶體中分配一個空間。它會分配 8 位的完整記憶體。儘管對於擁有近 12 萬億個此類位的儲存模組而言,這似乎並不重要,但在其他情況下卻很重要。一旦分配,該部分記憶體就會被使用,並且只有在操作完成後才能收回。考慮一個複雜的 Java 程式,其中您唯一使用的資料型別是 `long` 整數。當沒有空間進行更多記憶體分配作業時會發生什麼?您聽說過 **堆疊溢位錯誤** 嗎?這就是確切發生的事情——您的記憶體會被完全使用,而且速度很快。因此,請務必謹慎選擇資料型別。

說夠了,讓我們看看如何建立數值型別。數值型別以型別的名稱開頭(`short`、`int` 等),然後為記憶體中分配的空間提供一個名稱。以下是操作方式。假設我們需要建立一個變數來儲存一年中的天數。

Example 程式碼部分 3.54:一年中的天數。
short daysInYear = 365;

這裡,`daysInYear` 是變數的名稱,它儲存 `365` 作為其值,而 `short` 是該特定值的型別。Java 中整數資料型別的其他用途可能需要您編寫如下所示的程式碼

Example 程式碼部分 3.55:Java 中的整數資料型別。
byte maxByte = 127;
short maxShort = 32767;
int maxInt = 2147483647;
long maxLong = 9223372036854775807L;

整數和浮點數

[edit | edit source]

可以用於整數的資料型別是 `byte`、`short`、`int` 和 `long`,但是當涉及浮點數時,我們使用 `float` 或 `double`。現在我們知道了這一點,我們可以修改 程式碼部分 3.53 中的程式碼,如下所示

Example 程式碼部分 3.56:正確的浮點宣告和賦值。
double age = 10.5;

為什麼不是 `float`,您問?如果我們使用 `float`,則必須在數字末尾新增一個 `f` 作為字尾,因此 `10.5` 應該是 `10.5f`,如下所示

Example 程式碼部分 3.57:定義型別為 `float` 的浮點數的正確方法。
float age = 10.5f;

浮點數學永遠不會丟擲異常。將非零值除以 `0` 等於 `infinity`。將非無窮值除以 `infinity` 等於 `0`。

測試您的知識

**問題 3.7:**考慮以下程式碼

Example 問題 3.7:基本型別賦值。
...

a = false;
b = 3.2;
c = 35;
d = -93485L;
e = 'q';

這些是五個變數。有一個 `long`、一個 `byte`、一個 `char`、一個 `double` 和一個 `boolean`。獲取每個變數的型別。

答案
Example 答案 3.7:基本型別賦值和宣告。
boolean a;
double b;
byte c;
long d;
char e;

a = false;
b = 3.2;
c = 35;
d = -93485L;
e = 'q';
  • `a` 只能是 `boolean`,因為只有布林型別可以處理布林值。
  • `e` 只能是 `char`,因為只有字元型別可以包含一個字元。
  • `b` 只能是 `double`,因為只有雙精度型別可以包含此處的十進位制數。
  • `d` 是 `long`,因為 `byte` 無法包含如此小的值。
  • `c` 是剩下的一個,所以它是 `byte`。

資料轉換(強制轉換)

[edit | edit source]

資料轉換(強制轉換)可以在兩種基本型別之間進行。強制轉換有兩種型別

  • 隱式:不需要強制轉換操作;數值的大小始終保持不變。但是,從整數型別轉換為浮點型別時,可能會丟失 *精度*。
  • 顯式:需要強制轉換操作;數值的大小可能無法保持不變。
Example **程式碼部分 3.58:隱式強制轉換(int 轉換為 long,不需要強制轉換)。**
int  i = 65;
long l = i;
Example **程式碼部分 3.59:顯式強制轉換(long 轉換為 int,需要強制轉換)。**
long l = 656666L;
int  i = (int) l;

下表顯示了基本型別之間的轉換,它顯示了顯式轉換的強制轉換操作

byte char short int long float double boolean
byte - (byte) (byte) (byte) (byte) (byte) (byte) N/A
char - (char) (char) (char) (char) (char) N/A
short (short) - (short) (short) (short) (short) N/A
int - (int) (int) (int) N/A
long - (long) (long) N/A
float - (float) N/A
double - N/A
boolean N/A N/A N/A N/A N/A N/A N/A -

與 C、C++ 和類似語言不同,Java 無法將 `false` 表示為 `0` 或 `null`,也無法將 `true` 表示為非零。Java 無法從布林型別轉換為非布林基本資料型別,反之亦然。


對於非基本型別

到 Integer 到 Float 到 Double 到 String 到 Array
整數 - (float)x (double)x
x.doubleValue()
x.toString()
Float.toString(x)
new int[] {x}
Float java.text.DecimalFormat("#").format(x) - (double)x x.toString() new float[] {x}
Double java.text.DecimalFormat("#").format(x) java.text.DecimalFormat("#").format(x) - x.toString() new double[] {x}
String Integer.parseInt(x) Float.parseFloat(x) Double.parseDouble(x) - new String[] {x}
Array x[0] x[0] x[0] Arrays.toString(x) -

註釋

[edit | edit source]
  1. 根據 "STR01-J. Do not assume that a Java char fully represents a Unicode code point". Carnegie Mellon University - Software Engineering Institute. Retrieved 27 Nov 2018., 並非所有 Unicode 字元都適合 16 位表示。
  2. 截至編輯(2013 年 12 月 11 日),網際網路梅森素數大搜索 專案迄今為止已將最大的素數識別為 17,425,170 位。素數對於密碼學家來說很有價值,因為數字越大,他們就可以使用該特定數字使其資料加密邏輯更安全。
  3. 由於軟體錯誤,雙子座5號飛船在太平洋預定著陸點以西 130 公里處著陸。 地球自轉速度被程式設計為每太陽日旋轉一週,而不是正確的每恆星日旋轉一週。
  4. 他們設計中使用的程式使用了變數的算術和,而應該使用它們的絕對值的和。(Evars Witt,“小電腦和大問題”,美聯社新聞,1979 年 3 月 16 日。另見 Peter Neumann,“關於軟體正確性和社會過程的社論”軟體工程筆記,第 4 卷(2),1979 年 4 月,第 3 頁)


華夏公益教科書