นี่เป็นเนื้อหาใหม่ที่แนะนำหลังจาก jdk1.5 เนื่องจากฉันยืนยันว่าการเผยแพร่เป็นหน่วยความจำที่ดีที่สุด ฉันจึงตัดสินใจแทนที่หน่วยความจำด้วยบล็อก:
ข้อกำหนดภาษาจาวากล่าวว่า: ในหลายกรณีการบรรจุภัณฑ์และการแกะกล่องจะกระทำโดยคอมไพเลอร์เอง (ในกรณีนี้ การบรรจุภัณฑ์เรียกว่า boxing และการแกะกล่องเรียกว่า unboxing)
ตามความเข้าใจของฉันเอง การชกมวยอัตโนมัติสามารถเข้าใจได้ง่าย ๆ ว่าเป็นการห่อหุ้มประเภทข้อมูลพื้นฐานเป็นประเภทวัตถุเพื่อให้สอดคล้องกับการวางแนววัตถุของ Java เช่น ใช้ int เป็นตัวอย่าง:
คัดลอกรหัสรหัส ดังต่อไปนี้:
//ประกาศวัตถุจำนวนเต็ม
จำนวนเต็ม = 10;
//คำสั่งข้างต้นใช้การชกมวยอัตโนมัติ: แยกวิเคราะห์เป็น
Integer num = new Integer(10); ข้างต้นเป็นตัวอย่างที่ดี เนื่องจาก 10 เป็นของประเภทข้อมูลพื้นฐาน ไม่สามารถกำหนดให้กับวัตถุ Integer ได้โดยตรง แต่หลังจาก jdk1.5 คุณสามารถดำเนินการคำสั่งนี้ได้ เป็นเสน่ห์ของออโต้บ็อกซ์ในการแปลงประเภทข้อมูลพื้นฐานเป็นประเภทที่ห่อหุ้มที่สอดคล้องกันโดยอัตโนมัติ หลังจากที่กลายเป็นวัตถุแล้ว คุณสามารถเรียกใช้วิธีการทั้งหมดที่วัตถุประกาศไว้เพื่อแกะกล่องออกโดยอัตโนมัติ ดังนั้นชื่อจึงหมายถึงการแปลงวัตถุใหม่ให้เป็นประเภทข้อมูลพื้นฐาน:
//มวย
จำนวนเต็ม = 10;
//แกะกล่อง
int num1 = num; การใช้การแกะกล่องอัตโนมัติโดยทั่วไปคือเมื่อดำเนินการ: เนื่องจากวัตถุไม่ได้ถูกดำเนินการโดยตรง แต่จะต้องแปลงเป็นประเภทข้อมูลพื้นฐานก่อนจึงจะสามารถทำการบวก ลบ คูณหารได้
จำนวนเต็ม = 10;
// การแกะกล่องอัตโนมัตินั้นมีความหมายโดยนัยเมื่อทำการคำนวณ
System.out.print(num--); ฮ่าๆ คงจะดูเรียบง่ายกว่านี้หน่อย
//ตัวเลขภายนอก -128~127
จำนวนเต็ม num1 = 297; จำนวนเต็ม num2 = 297;
System.out.println("num1==num2: "+(num1==num2));
// หมายเลขภายใน -128~127
จำนวนเต็ม num3 = 97; จำนวนเต็ม num4 = 97;
System.out.println("num3==num4: "+(num3==num4)); ผลลัพธ์ที่พิมพ์คือ: num1==num2: false num3==num4: true
มันแปลก: นี่เป็นเพราะการออกแบบของ Java ของการชกมวยอัตโนมัติและการแกะกล่องของ Integer และ int มันเป็นโหมด: เรียกว่าโหมดฟลายเวท (ฟลายเวท)
เพื่อเพิ่มการนำตัวเลขธรรมดากลับมาใช้ใหม่ Java ให้คำจำกัดความว่า ระหว่างการชกอัตโนมัติ สำหรับค่าระหว่าง 128 ถึง 127 หลังจากใส่ลงในวัตถุ Integer แล้ว ตัวเลขเหล่านั้นจะถูกเก็บไว้ในหน่วยความจำเพื่อนำมาใช้ซ้ำและจะมีเพียงตัวเลขเดียวเสมอ วัตถุ และถ้ามันเกินค่าระหว่าง 128 ถึง 127 ค่า Inte ชนิดบรรจุกล่อง ger object จะไม่ถูกนำมาใช้ซ้ำซึ่งเทียบเท่ากับการสร้าง object Integer ใหม่ทุกครั้งที่บรรจุกล่อง เข้าใจครับ ปรากฏการณ์ข้างต้นเกิดจากการใช้การชกมวยอัตโนมัติ แต่ทำตาม Like คลาสทั่วไป หากคุณใช้ new เพื่อสร้างอินสแตนซ์ ออบเจ็กต์ใหม่จะถูกสร้างขึ้นทุกครั้งที่มีการใช้ใหม่
การชกมวยและการแกะกล่องอัตโนมัตินี้ไม่เพียงแต่ใช้ในประเภทข้อมูลพื้นฐานเท่านั้น แต่ยังใช้ในคลาส String ด้วย ตัวอย่างเช่น เมื่อเรามักจะประกาศออบเจ็กต์ String:
คัดลอกรหัสรหัส ดังต่อไปนี้:
สตริง str = "sl";
//แทนที่วิธีการประกาศต่อไปนี้
สตริง str = สตริงใหม่ ("sl");
Autoboxing และ unboxing ของข้อมูลพื้นฐาน (ดั้งเดิม) เป็นฟังก์ชันที่มีให้ตั้งแต่ J2SE 5.0 แม้ว่าจะอำนวยความสะดวกให้กับคุณในการจัดแพคเกจประเภทข้อมูลพื้นฐาน แต่ก็แนะนำให้ใช้เฉพาะเมื่อคุณสามารถแยกแยะความแตกต่างระหว่างประเภทข้อมูลพื้นฐานและออบเจ็กต์ได้
การทำกล่องอัตโนมัติและการแกะกล่อง
ใน Java เกือบทุกอย่างที่ต้องประมวลผลคือวัตถุ (Object) ตัวอย่างเช่น Scanner ที่ใช้ก่อนหน้านี้เป็นวัตถุและ String (String) ก็เป็นวัตถุเช่นกัน เราจะเห็นวัตถุเพิ่มเติมในภายหลัง อย่างไรก็ตาม ชนิดข้อมูลพื้นฐานไม่ใช่ออบเจ็กต์ นั่นคือตัวแปรที่คุณกำหนดโดยใช้ int, double, boolean ฯลฯ และค่าคงที่ตามตัวอักษรที่คุณเขียนโดยตรง
ในหัวข้อที่แล้ว เราได้เห็นคร่าวๆ ถึงความสะดวกในการใช้งาน Object แล้ว และใครก็ตามที่เคยใช้ Java มาระยะหนึ่งจะรู้ดีว่าบางครั้งจำเป็นต้องแปลงประเภทข้อมูลพื้นฐานให้เป็น Object ตัวอย่างเช่น เมื่อใช้เมธอด put() ของออบเจ็กต์ Map พารามิเตอร์ที่ต้องส่งผ่านจะเป็นออบเจ็กต์แทนที่จะเป็นประเภทข้อมูลพื้นฐาน
คุณต้องใช้ประเภท wrapper (Wrapper Types) เพื่อรวมประเภทข้อมูลพื้นฐานลงในอ็อบเจ็กต์ ในส่วนก่อนหน้านี้ คุณรู้อยู่แล้วว่าก่อน J2SE 5.0 คุณต้องใช้คำสั่งต่อไปนี้เพื่อรวม int ลงในอ็อบเจ็กต์ Integer: Integer integer = new จำนวนเต็ม(10) ;
ฟังก์ชัน auto-boxing มีให้หลังจาก J2SE 5.0 คุณสามารถใช้คำสั่งต่อไปนี้เพื่อแพ็กประเภทข้อมูลพื้นฐานได้โดยตรง: Integer integer = 10;
เมื่อทำการคอมไพล์ คอมไพเลอร์จะกำหนดโดยอัตโนมัติว่าจะดำเนินการชกมวยอัตโนมัติตามคำสั่งที่คุณเขียนหรือไม่ ในตัวอย่างข้างต้น จำนวนเต็มหมายถึงอินสแตนซ์ของคลาสจำนวนเต็ม การดำเนินการเดียวกันนี้สามารถนำไปใช้กับประเภทข้อมูลพื้นฐานได้ เช่น บูลีน ไบต์ สั้น ถ่าน ยาว ลอย สองเท่า ฯลฯ ประเภทแรปเปอร์ที่สอดคล้องกัน (ประเภทแรปเปอร์) บูลีน ไบต์ สั้น อักขระ ยาว ลอย หรือดับเบิลจะ ถูกนำมาใช้ตามลำดับ ลองใช้ฟังก์ชัน autoboxing โดยตรงเพื่อเขียนตัวอย่างที่ 4.4 ใหม่
ตัวอย่าง 4.5 AutoBoxDemo.java
คัดลอกรหัสรหัส ดังต่อไปนี้:
AutoBoxDemo คลาสสาธารณะ {
โมฆะคงที่สาธารณะ main (String [] args) {
ข้อมูลจำนวนเต็ม1 = 10;
ข้อมูลจำนวนเต็ม2 = 20;
//แปลงเป็นค่าสองเท่าแล้วหารด้วย 3
System.out.println(data1.doubleValue() / 3);
//เปรียบเทียบสองค่า
System.out.println(data1.compareTo(data2));
-
-
ดูเหมือนว่าโปรแกรมจะง่ายกว่ามาก data1 และ data2 เป็นอินสแตนซ์ของ Integer ณ รันไทม์และสามารถดำเนินการกับวัตถุได้โดยตรง ผลลัพธ์จะเป็นดังนี้:
3.333333333333335
1
วิธีการใช้มวยอัตโนมัติอาจเป็นดังนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
อินท์ i = 10;
จำนวนเต็ม จำนวนเต็ม = i;
คุณยังสามารถใช้คลาส java.lang.Number ทั่วไปสำหรับการทำ autoboxing ได้ ตัวอย่างเช่น:
หมายเลขหมายเลข = 3.14f;
3.14f จะถูกบรรจุอยู่ในกล่องลอยโดยอัตโนมัติ จากนั้นจึงกำหนดให้กับหมายเลข
เริ่มต้นจาก J2SE 5.0 การชกมวยอัตโนมัติและการแกะกล่องอัตโนมัตินั้นมีให้ใช้งาน นั่นคือ ข้อมูลแบบฟอร์มข้อมูลพื้นฐานในออบเจ็กต์จะถูกนำออกจากออบเจ็กต์โดยอัตโนมัติ ตัวอย่างเช่น สามารถเขียนได้ดังนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
จำนวนเต็ม fooInteger = 10;
int fooPrimitive = fooInteger;
หลังจากที่ fooInteger ถูกอ้างอิงถึงอินสแตนซ์ที่บรรจุกล่องเป็น Integer โดยอัตโนมัติ หากถูกกำหนดให้กับตัวแปร fooPrimitive ประเภท int ก็จะถูกเปลี่ยนเป็นประเภท int โดยอัตโนมัติ จากนั้นกำหนดให้กับ fooPrimitive ในระหว่างการดำเนินการสามารถทำการชกมวยและแกะกล่องอัตโนมัติได้ ตัวอย่างเช่น:
คัดลอกรหัสรหัส ดังต่อไปนี้:
จำนวนเต็ม i = 10;
System.out.println(i + 10);
System.out.println(i++);
ในตัวอย่างข้างต้น 20 และ 10 จะถูกแสดง คอมไพเลอร์จะดำเนินการ boxing และ unboxing โดยอัตโนมัติ นั่นคือ 10 จะถูก boxed ก่อน จากนั้นจึง unboxed ก่อนเมื่อ i + 10 และการดำเนินการเพิ่มเติมจะดำเนินการ บรรทัดจะถูกใส่กล่องก่อน จากนั้นจึงดำเนินการเพิ่ม ลองดูตัวอย่างอื่น:
คัดลอกรหัสรหัส ดังต่อไปนี้:
บูลีนบู = จริง;
System.out.println(บู && เท็จ);
เดิมที Boo เดียวกันนี้เป็นอินสแตนซ์ของ Boolean เมื่อดำเนินการ AND boo จะถูกแกะกล่องออกก่อน จากนั้นจึง AND ด้วย false และผลลัพธ์จะแสดงเป็น false
//////////////////////////////////////////////// /////////////////////
Boxing: การแปลงจากประเภทพื้นฐานเป็นประเภท Object เรียกว่า boxing *** Unboxing: การดำเนินการแปลงจาก Object เป็นประเภทพื้นฐานเรียกว่า unboxing การดำเนินการนี้มักใช้ในกระบวนการสะท้อนกลับ
การบรรจุ: สร้างอินสแตนซ์ออบเจ็กต์ในฮีปและคัดลอกค่าที่คุณระบุ ***แกะกล่อง: ตรวจสอบว่าข้อมูลในฮีปที่อ้างอิงไปเป็นประเภทที่จะแยก และรับค่าจากฮีปแล้วส่ง ไปยังตัวแปรสแต็ก มิฉะนั้นจะมีการรายงานข้อยกเว้น
//////////////////////////////////////////////// ////////////////////////
การชกมวยคือการแปลงฤาษีประเภทค่าเป็นประเภทวัตถุหรือประเภทอินเทอร์เฟซใด ๆ ที่ใช้ประเภทค่านั้น
การ Boxing ประเภทค่าจะจัดสรรอินสแตนซ์ของวัตถุและคัดลอกค่าลงในวัตถุใหม่
คัดลอกรหัสรหัส ดังต่อไปนี้:
อินท์ i=123;
วัตถุ o=i;
ผลลัพธ์ของประโยคนี้คือการสร้างวัตถุ o บนสแต็ก ซึ่งอ้างอิงค่าประเภท int บนฮีป ค่านี้ถูกกำหนดให้กับตัวแปร i
สำเนาของค่าชนิดค่า
ด้านล่างเป็นจอแสดงผลที่ทำการแปลงมวย
คัดลอกรหัสรหัส ดังต่อไปนี้:
อินท์ i=123;
วัตถุ o=(วัตถุ)i;
ตัวอย่างนี้แปลงตัวแปรจำนวนเต็ม i ไปเป็นอ็อบเจ็กต์ o ผ่านการ Boxing ด้วยวิธีนี้ ค่าที่เก็บไว้ในตัวแปร i จะเปลี่ยนจาก 123 เป็น 456 ตัวอย่างนี้แสดงให้เห็นว่าออบเจ็กต์เก็บสำเนาต้นฉบับของเนื้อหาไว้ นั่นคือ 123.
Unboxing คือการแปลงอย่างชัดเจนจากประเภทออบเจ็กต์ไปเป็นประเภทค่า หรือจากประเภทอินเทอร์เฟซไปเป็นประเภทค่าที่ใช้อินเทอร์เฟซ การดำเนินการแกะกล่องประกอบด้วย:
ตรวจสอบอินสแตนซ์ของวัตถุเพื่อให้แน่ใจว่าเป็นค่าชนิดบรรจุกล่องของประเภทค่าที่กำหนด
คัดลอกค่าจากอินสแตนซ์ไปยังตัวแปรประเภทค่า
ตัวอย่าง:
คัดลอกรหัสรหัส ดังต่อไปนี้:
อินท์ i=123;
กล่องวัตถุ = i;
int j=(int)กล่อง;