你好!隨著您在 CodeGym 中的進步,您已經多次遇到原始類型。以下是我們對它們的了解的簡短列表:
- 它們不是對象,代表存儲在內存中的值
- 有幾種
- 整數:byte、short、int、long
- 浮點(小數)數:float和double
- 邏輯值:布爾
- 符號值(用於表示字母和數字):char
-
每種類型都有自己的取值範圍:
原始類型 |
內存大小 |
取值範圍 |
字節 |
8位 |
-128 到 127 |
短的 |
16位 |
-32768 至 32767 |
字符 |
16位 |
0 到 65536 |
整數 |
32位 |
-2147483648 至 2147483647 |
長的 |
64位 |
-9223372036854775808 至 9223372036854775807 |
漂浮 |
32位 |
(2 的 -149 次方) 到 ((2 - (2 的 -23 次方)) * 2 的 127 次方) |
雙倍的 |
64位 |
(-2 的 63 次方) 到 ((2 的 63 次方) - 1) |
布爾值 |
8(在數組中使用時),32(如果不在數組中使用) |
對或錯 |
但除了具有不同的值外,它們在內存中佔用的空間也不同。一個
int佔用的不僅僅是一個字節。多頭比空頭大
。原始人佔用的內存量可以與俄羅斯套娃進行比較:
每個套娃內部都有可用空間。嵌套娃娃越大,空間就越大。一個大的嵌套娃娃(
長)很容易容納一個較小的
int。它很容易安裝,你不需要做任何其他事情。在 Java 中,當使用原語時,這稱為隱式轉換。或者換句話說,它被稱為拓寬。
在 Java 中加寬
這是一個擴大轉換的簡單示例:
public class Main {
public static void main(String[] args) {
int bigNumber = 10000000;
byte littleNumber = 16;
bigNumber = littleNumber;
System.out.println(bigNumber);
}
}
這裡我們將一個 byte 值賦給一個
int變量。分配成功沒有任何問題:存儲在字節中的值佔用的內存少於
int可以容納的內存。小嵌套娃娃(字節值)很容易放入大嵌套娃娃(
int變量)中。如果您嘗試做相反的事情,即把一個大的值放入一個範圍不能容納如此大的數據類型的變量中,那就另當別論了。對於真正的嵌套娃娃,這個數字根本放不下。使用 Java,它可以,但有細微差別。讓我們嘗試將一個
int放入一個
short變量中:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = bigNumber;
System.out.println(bigNumber);
}
錯誤!
編譯器知道您試圖通過將一個大嵌套娃娃 ( int ) 推到一個小嵌套娃娃 (
short ) 中來做一些不正常的事情。在這種情況下,編譯錯誤是來自編譯器的警告:“嘿,你
確定要這樣做嗎?” 如果你確定,那麼你告訴編譯器:
“一切都很好。我知道我在做什麼!” 此過程稱為顯式類型轉換或縮小。
在 Java 中縮小
要執行縮小轉換,您需要明確指示要將值轉換為的類型。換句話說,你需要回答編譯器的問題:
“嗯,你想把這個大嵌套娃娃放到這些小嵌套娃娃中的哪個?” 在我們的例子中,它看起來像這樣:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = (short) bigNumber;
System.out.println(littleNumber);
}
我們明確表示我們想將一個
int放入一個
short變量中,我們將承擔責任。看到已顯式指示更窄的類型,編譯器執行轉換。結果如何?控制台輸出:
-27008 這有點出乎意料。為什麼我們得到那個?事實上,這一切都很簡單。原來,這個值是 10000000 ,它被存儲在一個
int變量中,它佔用 32 位。這是它的二進製表示:
我們把這個值寫入一個
short變量,它只能存儲16位!因此,只有我們數字的前 16 位會被移到那裡。其餘的將被丟棄。結果,short 變量接收到以下值
十進制形式等於 -27008 這就是編譯器要求您通過指示對特定類型的顯式縮小轉換來“確認”的原因。首先,這表明你對結果負責。其次,它告訴編譯器在轉換發生時要分配多少空間。畢竟,在最後一個示例中,如果我們將 int 值分配給 byte 變量而不是 short
,那麼我們只能使用 8 位,而不是 16 位,結果會有所不同。分數類型(
float和
double)有自己的縮小轉換的過程。如果您嘗試將小數轉換為整數類型,小數部分將被丟棄。
public static void main(String[] args) {
double d = 2.7;
long x = (int) d;
System.out.println(x);
}
控制台輸出:
2
字符
您已經知道
char用於顯示單個字符。
public static void main(String[] args) {
char c = '!';
char z = 'z';
char i = '8';
}
但是這種數據類型有幾個需要理解的重要特性。讓我們再看一下取值範圍表:
原始類型 |
內存大小 |
取值範圍 |
字節 |
8位 |
-128 到 127 |
短的 |
16位 |
-32768 至 32767 |
字符 |
16位 |
0 到 65536 |
整數 |
32位 |
-2147483648 至 2147483647 |
長的 |
64位 |
-9223372036854775808 至 9223372036854775807 |
漂浮 |
32位 |
(2 的 -149 次方) 到 ((2 - (2 的 -23 次方)) * 2 的 127 次方) |
雙倍的 |
64位 |
(-2 的 63 次方) 到 ((2 的 63 次方) - 1) |
布爾值 |
8(在數組中使用時),32(如果不在數組中使用) |
對或錯 |
0 到 65536 的範圍表示為
char類型。但是,這是什麼意思?畢竟,
char不僅代表數字,還代表字母、標點符號……關鍵是在 Java 中,
char值以 Unicode 格式存儲。我們已經在之前的課程中遇到過 Unicode。您可能記得 Unicode 是一種字符編碼標準,它包括世界上幾乎所有書面語言的符號。換句話說,它是一個特殊代碼列表,幾乎可以代表任何語言中的每個字符。整個 Unicode 表非常大,當然沒必要死記硬背。這是其中的一小部分:
最主要的是理解字符是如何存儲的,並記住如果你知道特定字符的代碼,你總是可以在你的程序中產生那個字符。讓我們嘗試一些隨機數:
public static void main(String[] args) {
int x = 32816;
char c = (char) x ;
System.out.println(c);
}
控制台輸出:耰 這是 Java 中用於存儲char 的 格式。每個符號對應一個數字:一個 16 位(兩個字節)的數字代碼。在 Unicode 中,32816 對應漢字耰。 請注意以下幾點。在這個例子中,我們使用了一個
int變量。它在內存中佔用 32 位,而
char佔用 16 位。這裡我們選擇了
int,因為我們的數字 (32816) 放不下
short。
儘管char的大小(就像
short一樣)是 16 位,但char範圍內沒有負數,因此
char的“正數”部分
範圍是兩倍大(65536 而不是
short類型的 32767)。只要我們的代碼保持在 65536 以下,我們就可以使用
int。但是如果你創建一個大於 65536 的
int值,那麼它會佔用超過 16 位。這將導致縮小轉換
char c = (char) x;
多餘的位將被丟棄(如上所述),結果將是非常出乎意料的。
添加字符和整數的特殊功能
讓我們看一個不尋常的例子:
public class Main {
public static void main(String[] args) {
char c = '1';
int i = 1;
System.out.println(i + c);
}
}
控制台輸出:
50 O_О 這有什麼意義?1+1。哪來的50?!您已經知道
char
值在內存中存儲為 0 到 65536 範圍內的數字,並且這些數字是字符的 Unicode 表示。
當我們添加一個
char和一些整數類型時,
char被轉換為相應的 Unicode 數字。在我們的代碼中,當我們添加 1 和 '1' 時,符號 '1' 被轉換為它自己的代碼,即 49(您可以在上表中驗證這一點)。因此,結果是50。讓我們再次以我們的老朋友耰為例,嘗試將它加到某個數字上。
public static void main(String[] args) {
char c = '耰';
int x = 200;
System.out.println(c + x);
}
控制台輸出:
33016 我們已經發現耰 對應 32816。當我們將這個數字與 200 相加時,我們得到結果:33016。:) 如您所見,這裡的算法非常簡單,但您不要忘記它.