1. 類型轉換

Java 中的類型轉換

原始類型的變量(類型除外boolean)用於存儲各種類型的數字。儘管變量的類型從未改變,但在某個地方您可以從一種類型轉換為另一種類型。那個地方就是assignment

不同類型的變量可以相互賦值。執行此操作時,一種類型的變量的值將轉換為另一種類型的值並分配給第二個變量。在這方面,我們可以識別兩種類型轉換:擴大和縮小。

擴大就像將一個值從一個小籃子移動到一個大籃子:這個操作是無縫且無痛的。當您將一個值從一個大籃子移到一個小籃子時,就會發生變窄:可能沒有足夠的空間,您將不得不扔掉一些東西。

以下是按籃子大小排序的類型:

Java 2 中的類型轉換


2. 擴大類型轉換

通常需要將一種數值類型的變量賦值給另一種數值類型的變量。你是怎樣做的?

Java 有 4 種整數類型:

類型 尺寸
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

存儲在較小籃子中的變量總是可以分配給存儲在較大籃子中的變量。

int,short變量byte可以很容易地分配給long變量。short變量byte可以賦值給int變量。並且byte變量可以賦值給short變量。

例子:

代碼 描述
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
這段代碼將編譯得很好。

這種從較小類型到較大類型的轉換稱為加寬類型轉換。

實數呢?

有了它們,一切都一樣——大小很重要:

類型 尺寸
float 4 bytes
double 8 bytes

floatdouble變量可以毫無問題地賦值給變量。但是整數類型的事情更有趣。

您可以將任何整數變量分配給一個float變量。即使long是 8 字節長的類型。您可以將任何您想要的 - 任何整數變量或float變量 - 分配給一個double變量:

代碼 筆記
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

請注意,由於缺少足夠的有效數字,轉換為實數類型可能會導致精度損失。

從整數轉換為浮點數時,數字的低階部分可能會被丟棄。但由於小數被理解為存儲近似值,因此允許進行此類賦值操作。


3.縮小類型轉換

那其他的可能性呢?如果需要longint變量賦值怎麼辦?

將變量想像成一個籃子。我們有各種大小的籃子:1、2、4 和 8 字節。將蘋果從較小的籃子轉移到較大的籃子不是問題。但是,當從較大的籃子轉移到較小的籃子時,一些蘋果可能會丟失。

這種從較大類型到較小類型的轉換稱為縮小類型轉換。當執行這樣的賦值操作時,數字的一部分可能根本不適合新變量,因此可能會被丟棄。

縮小類型時,我們必須明確告訴編譯器我們沒有犯錯,我們是故意丟棄部分數字。類型轉換運算符用於此。它是括號中的類型名稱

在這種情況下,Java 編譯器要求程序員指定類型轉換運算符。一般來說,它看起來像這樣:

(type) expression

例子:

代碼 描述
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
每次都必須顯式指示類型轉換運算符

這裡a等於1,也許類型轉換運算符看起來有點矯枉過正。但如果a更大呢?

代碼 描述
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

一百萬完全適合 along和 an int。但是給一個short變量賦值一百萬時,前兩個字節被丟棄,只保留最後兩個字節。當分配給 a 時byte,唯一剩下的就是最後一個字節。

數字在內存中的排列方式:

類型 二進制符號 十進製表示法
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

char類型

Achar和 a 一樣short,佔用兩個字節,但要將一個字節轉換為另一個字節,您始終需要使用類型轉換運算符。這裡的問題是short類型是有符號的並且可以包含從-32,768到的值+32,767,但是char類型是無符號的並且可以包含從0到的值65,535

負數不能存儲在 a 中char,但可以存儲在 a 中short。並且 ashort不能存儲大於的數字32,767,但是這樣的數字可以存儲在 a 中char


4. 表達式類型

如果在同一個表達式中使用不同類型的變量怎麼辦?從邏輯上講,我們理解首先需要將它們轉換為通用類型。但是哪一個?

當然是大一點的。

Java 總是轉換為更大的類型。粗略地說,首先擴大其中一個類型,然後才使用相同類型的值執行操作。

如果表達式中包含anint和a long,則將a的值int轉換為a long,然後才進行操作:

代碼 描述
int a = 1;
long b = 2;
long c = a + b;
a將擴大到 along然後添加將發生。

浮點數字

如果表達式中涉及整數和浮點數(floatdouble),則將整數轉換為浮點數(floatdouble),然後才執行運算。

如果操作涉及 afloat和 a double,則 thefloat將轉換為 a double。這實際上是預期的。

驚喜

、和類型在相互交互時byte總是轉換為。該類型被視為標準整數類型是有充分理由的。shortcharintint

如果將 a 乘以bytea short,您將得到 an int。如果將 a 乘以bytea byte,您將得到 an int。即使您添加 abyte和 a byte,您也會得到 an int

有幾個原因。例子:

代碼 描述
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 12013,200,它略大於該類型的最大值byte127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120230,它也略大於該類型的最大值byte127

一般來說,一個8位(1字節)的數乘以一個8位(1字節)的數,得到一個佔用16位(2字節)位的數

因此,所有具有小於 的整數類型的操作int總是立即轉換為ints。這意味著如果您想將計算結果存儲在類型小於 的變量中int,那麼您將始終需要顯式指定類型轉換運算符。

例子:

代碼 描述
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
byte * byte表達式將是一個int
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
byte + byte表達式將是一個int
byte a = 1;
byte b = (byte) (a + 1);
表達式byte + int將是 anint
字面值是 an int

5.一個重要的細微差別

類型轉換運算符具有相當高的優先級。

這意味著如果表達式包含,例如,加法和類型轉換運算符,則類型轉換將在加法之前執行。

例子:

代碼 描述
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
類型轉換運算符將僅應用於a已經是byte. 這段代碼不會編譯。
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
這是正確的方法。

如果要將整個表達式轉換為特定類型,而不僅僅是表達式的一個組成部分,則將整個表達式括在括號中並將類型轉換運算符放在前面。