1. การพิมพ์

Typecasting ใน Java

ตัวแปรประเภทดั้งเดิม (ยกเว้นประเภทboolean) ใช้เพื่อจัดเก็บตัวเลขประเภทต่างๆ แม้ว่าประเภทของตัวแปรจะไม่เคยเปลี่ยนแปลง แต่ก็มีที่ที่คุณสามารถแปลงจากประเภทหนึ่งไปเป็นอีกประเภทหนึ่งได้ และสถานที่นั้นคืองาน

สามารถกำหนดตัวแปรประเภทต่างๆ ให้กันได้ เมื่อคุณทำเช่นนี้ ค่าของตัวแปรประเภทหนึ่งจะถูกแปลงเป็นค่าของอีกประเภทหนึ่งและกำหนดให้กับตัวแปรตัวที่สอง ในเรื่องนี้ เราสามารถระบุการแปลงประเภทได้สองประเภท: การขยายและการทำให้แคบลง

การขยับขยายก็เหมือนกับการย้ายค่าจากตะกร้าใบเล็กไปยังตะกร้าใบใหญ่ การดำเนินการนี้ราบรื่นและไม่เจ็บปวด การทำให้แคบลงเกิดขึ้นเมื่อคุณย้ายค่าจากตะกร้าใบใหญ่ไปยังตะกร้าใบเล็ก: อาจมีพื้นที่ไม่เพียงพอ และคุณจะต้องทิ้งบางสิ่งไป

นี่คือประเภท เรียงตามขนาดตะกร้า:

Typecasting ใน Java 2


2. การขยายประเภทการแปลง

บ่อยครั้งที่จำเป็นต้องกำหนดตัวแปรที่เป็นตัวเลขประเภทหนึ่งให้กับตัวแปรที่เป็นตัวเลขอีกประเภทหนึ่ง คุณทำอย่างนั้นได้อย่างไร?

Java มี 4 ประเภทจำนวนเต็ม:

พิมพ์ ขนาด
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

ตัวแปรที่จัดเก็บไว้ในตะกร้าขนาดเล็กสามารถกำหนดให้กับตัวแปรที่จัดเก็บไว้ในตะกร้าขนาดใหญ่ได้เสมอ

intและ กำหนด ตัวแปรให้กับตัวแปรshortได้byteง่าย และสามารถกำหนดตัวแปรให้กับตัวแปรได้ และสามารถกำหนดตัวแปรให้กับตัวแปรได้longshortbyteintbyteshort

ตัวอย่าง:

รหัส คำอธิบาย
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
รหัสนี้จะรวบรวมได้ดี

การแปลงดังกล่าว จากประเภทที่เล็กลงเป็นประเภทที่ใหญ่ขึ้น เรียกว่าการแปลงประเภทที่กว้างขึ้น

แล้วจำนวนจริงล่ะ?

เมื่อมีทุกอย่างเหมือนกัน ขนาดก็สำคัญ:

พิมพ์ ขนาด
float 4 bytes
double 8 bytes

floatสามารถกำหนดตัวแปรให้กับdoubleตัวแปรได้โดยไม่มีปัญหาใดๆ แต่สิ่งที่น่าสนใจกว่าคือประเภทจำนวนเต็ม

คุณสามารถกำหนดตัวแปรจำนวนเต็มให้กับfloatตัวแปร แม้แต่longประเภทที่มีความยาว 8 ไบต์ และคุณสามารถกำหนดสิ่งที่คุณต้องการ — ตัวแปรจำนวนเต็มหรือfloatตัวแปร — ให้กับdoubleตัวแปร:

รหัส บันทึก
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

โปรดทราบว่าการแปลงเป็นประเภทจริงอาจทำให้สูญเสียความแม่นยำเนื่องจากไม่มีตัวเลขที่มีนัยสำคัญเพียงพอ

เมื่อแปลงจากจำนวนเต็มเป็นตัวเลขทศนิยม ลำดับล่างของตัวเลขอาจถูกละทิ้ง แต่เนื่องจากเข้าใจว่าตัวเลขเศษส่วนเก็บค่าโดยประมาณ จึงอนุญาตให้ดำเนินการมอบหมายดังกล่าวได้


3. การแปลงประเภทที่แคบลง

แล้วความเป็นไปได้อื่นๆ ล่ะ? จะทำอย่างไรถ้าคุณต้องการกำหนดlongค่าให้กับintตัวแปร

ลองนึกภาพตัวแปรเป็นตะกร้า เรามีตะกร้าหลายขนาด: 1, 2, 4 และ 8 ไบต์ การย้ายแอปเปิ้ลจากตะกร้าใบเล็กไปยังตะกร้าใบใหญ่นั้นไม่ใช่ปัญหา แต่เมื่อเปลี่ยนจากตะกร้าที่ใหญ่ขึ้นเป็นตะกร้าที่เล็กลง แอปเปิ้ลบางส่วนอาจหายไป

การแปลงนี้ — จากประเภทที่ใหญ่ขึ้นเป็นประเภทที่เล็กลง – เรียกว่าการแปลงประเภทที่แคบลง เมื่อดำเนินการกำหนดเช่นนี้ ส่วนหนึ่งของตัวเลขอาจไม่พอดีกับตัวแปรใหม่และอาจถูกละทิ้ง

เมื่อจำกัดประเภทให้แคบลง เราต้องบอกคอมไพเลอร์อย่างชัดเจนว่าเราไม่ได้ทำผิดพลาด เราจงใจละทิ้งส่วนหนึ่งของตัวเลข ใช้ตัวดำเนินการ typecast สำหรับสิ่งนี้ เป็นชื่อประเภทในวงเล็บ

ในสถานการณ์เช่นนี้คอมไพเลอร์ Javaต้องการให้โปรแกรมเมอร์ระบุตัวดำเนินการ typecast โดยทั่วไปจะมีลักษณะดังนี้:

(type) expression

ตัวอย่าง:

รหัส คำอธิบาย
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
แต่ละครั้งต้องระบุตัวดำเนินการ typecast อย่างชัดเจน

ที่นี่aเท่ากับ1และบางทีตัวดำเนินการ typecast ดูเหมือนจะเกินความจำเป็น แต่ถ้าaใหญ่กว่าล่ะ?

รหัส คำอธิบาย
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

หนึ่งล้านพอดีกับ a longและในint. แต่เมื่อกำหนดหนึ่งล้านให้กับshortตัวแปร สองไบต์แรกจะถูกละทิ้ง และเหลือเพียงสองไบต์สุดท้ายเท่านั้น และเมื่อกำหนดให้ a byteสิ่งเดียวที่เหลือคือไบต์สุดท้าย

วิธีจัดเรียงตัวเลขในหน่วยความจำ:

พิมพ์ สัญกรณ์ไบนารี เครื่องหมายทศนิยม
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0บ01000000 64

charพิมพ์

A charเช่น a shortใช้พื้นที่สองไบต์ แต่หากต้องการแปลงเป็นอีกอันหนึ่ง คุณต้องใช้ตัวดำเนินการ typecast เสมอ ปัญหาที่นี่คือshortประเภทมีการลงนามและสามารถมีค่าจากถึง-32,768แต่+32,767ประเภทcharไม่ได้ลงนามและสามารถมีค่าจาก0ถึง65,535

ไม่สามารถเก็บจำนวนลบใน a แต่charสามารถเก็บไว้ใน shortและshortไม่สามารถเก็บตัวเลขที่มากกว่า32,767แต่สามารถเก็บตัวเลขดังกล่าวในchar.


4. ประเภทของนิพจน์

จะเกิดอะไรขึ้นหากใช้ตัวแปรประเภทต่างๆ ในนิพจน์เดียวกัน ตามเหตุผลแล้ว เราเข้าใจว่าต้องแปลงเป็นประเภททั่วไปก่อน แต่ที่หนึ่ง?

สำหรับคนที่ใหญ่กว่าแน่นอน

Java จะแปลงเป็นประเภทที่ใหญ่กว่าเสมอ พูดอย่างคร่าว ๆ ว่าประเภทใดประเภทหนึ่งจะถูกขยายก่อน จากนั้นจึงดำเนินการโดยใช้ค่าประเภทเดียวกันเท่านั้น

ถ้า an intและ a longเกี่ยวข้องกับนิพจน์ ค่าของ the intจะถูกแปลงเป็น a longและจากนั้นการดำเนินการจะดำเนินการต่อ:

รหัส คำอธิบาย
int a = 1;
long b = 2;
long c = a + b;
aจะขยายเป็น a longแล้วการบวกจะเกิดขึ้น

ตัวเลขทศนิยม

หากจำนวนเต็มและเลขทศนิยม ( floatหรือdouble) เกี่ยวข้องกับนิพจน์ จำนวนเต็มจะถูกแปลงเป็นเลขทศนิยม ( floatหรือdouble) และจากนั้นจะดำเนินการเท่านั้น

หากการดำเนินการเกี่ยวข้องกับ a floatและ a doubleการดำเนินการนั้นfloatจะถูกแปลงเป็นdoublea ซึ่งเป็นไปตามคาดจริงๆ

เซอร์ไพรส์

, , และประเภทจะถูกแปลงเป็นเสมอ เมื่อ byteมีการโต้ตอบระหว่างกัน มีเหตุผลที่ดีว่าทำไมประเภทจึงถือเป็นประเภทจำนวนเต็มมาตรฐานshortcharintint

หากคุณคูณ a byteด้วย a คุณ จะshortได้ intหากคุณคูณ a byteด้วย a คุณ จะbyteได้ intแม้ว่าคุณจะเพิ่ม a byteและ a คุณก็ จะbyteได้int

มีหลายสาเหตุนี้. ตัวอย่าง:

รหัส คำอธิบาย
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120คือ13,200ซึ่งมากกว่าค่าสูงสุดของbyteประเภทเล็กน้อย:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120คือ230ซึ่งมากกว่าค่าสูงสุดของbyteประเภทเล็กน้อยด้วย:127

โดยทั่วไป เมื่อคูณเลข 8 บิต (1 ไบต์) ด้วยเลข 8 บิต (1 ไบต์) เราจะได้ตัวเลขที่ใช้พื้นที่บิต 16 บิต (2 ไบต์)

ด้วยเหตุนี้ การดำเนินการทั้งหมดที่มีประเภทจำนวนเต็มที่น้อยกว่า จะถูกแปลงเป็น s intทันที intและนั่นหมายความว่าหากคุณต้องการเก็บผลลัพธ์ของการคำนวณไว้ในตัวแปรประเภทที่เล็กกว่าintคุณจะต้องระบุตัวดำเนินการ typecast อย่างชัดเจนเสมอ

ตัวอย่าง:

รหัส คำอธิบาย
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จะเป็น an int
ตัวอักษรคือintan

5. ความแตกต่างที่สำคัญ

ตัวดำเนินการ typecast มีลำดับความสำคัญค่อนข้างสูง

ซึ่งหมายความว่าหากนิพจน์ประกอบด้วย ตัวอย่างเช่น การบวกและตัวดำเนินการ typecast จะดำเนินการ typecast ก่อนการบวก

ตัวอย่าง:

รหัส คำอธิบาย
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
ตัวดำเนินการ typecast จะถูกนำไปใช้กับaตัวแปรซึ่งเป็นbyte. รหัสนี้จะไม่รวบรวม
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
นี่คือวิธีที่ถูกต้อง

หากคุณต้องการแปลงนิพจน์ทั้งหมดเป็นประเภทเฉพาะ ไม่ใช่แค่ส่วนใดส่วนหนึ่งของนิพจน์ ให้รวมนิพจน์ทั้งหมดไว้ในวงเล็บแล้วใส่ตัวดำเนินการ typecast ไว้ข้างหน้า