สระว่ายน้ำคงที่ของ Java มักจะแบ่งออกเป็นสองประเภท: สระว่ายน้ำคงที่และสระว่ายน้ำคงที่รันไทม์
พูลคงที่คงที่: พูลคงที่ในไฟล์คลาส พูลคงที่ในไฟล์คลาสประกอบด้วยค่าสตริง (หมายเลข) ข้อมูลตัวอักษรคลาสและวิธีการใช้พื้นที่ส่วนใหญ่ในไฟล์คลาส
Runtime Constant Pool: หลังจาก JVM เสร็จสิ้นการโหลดคลาสแล้วมันจะโหลดพูลคงที่ในไฟล์คลาสลงในหน่วยความจำและบันทึกไว้ในพื้นที่เมธอด สิ่งที่เรามักจะพูดถึงคือสระว่ายน้ำคงที่ของสระคงที่รันไทม์ในพื้นที่วิธีการ คุณสมบัติที่สำคัญอีกประการหนึ่งของพูลคงที่เมื่อเทียบกับไฟล์คลาสคือไดนามิก ภาษา Java ไม่จำเป็นต้องมีค่าคงที่เฉพาะในช่วงระยะเวลาการรวบรวมนั่นคือเนื้อหาของพูลคงที่ในไฟล์คลาสสามารถเข้าสู่พื้นที่วิธีการรันไทม์ของพื้นที่วิธีการรันไทม์ ในระหว่างการวิ่งค่าคงที่ใหม่อาจถูกวางลงในสระ คุณลักษณะนี้ใช้กันทั่วไปโดยนักพัฒนา วิธีการฝึกงาน () ของคลาสสตริง
ตัวนับโปรแกรม: เป็นไปป์ไลน์สำหรับการดำเนินการโปรแกรมโดยระบุว่าคำสั่งใดที่จะเรียกใช้งานถัดไป
สแต็ควิธีการท้องถิ่น: สแต็กที่ใช้โดย JVM เพื่อเรียกวิธีการระบบปฏิบัติการ
สแต็คเครื่องเสมือน: สแต็กที่ใช้โดย JVM เพื่อเรียกใช้รหัส Java
กองเสมือนจริงกอง: ที่เก็บวัตถุและวัตถุทั้งหมดที่ใหม่ในโปรแกรม Java จะถูกเก็บไว้ในกอง
พื้นที่วิธีการ: ค่าคงที่ของร้านค้า, ข้อมูลชั้นเรียนและตัวแปรคงที่ซึ่งสามารถเข้าใจได้ว่าเป็นตำแหน่งที่เก็บไฟล์คลาสไว้ในหน่วยความจำ
ประโยชน์ของการรวมกันอย่างต่อเนื่อง:
สระว่ายน้ำคงที่เพื่อหลีกเลี่ยงการสร้างและการทำลายวัตถุที่ส่งผลกระทบต่อประสิทธิภาพของระบบบ่อยครั้งและพวกเขาตระหนักถึงการแบ่งปันวัตถุ
ตัวอย่างเช่นสระว่ายน้ำคงที่สตริงจะใช้เพื่อใส่ตัวอักษรสตริงทั้งหมดลงในพูลคงที่ในระหว่างขั้นตอนการรวบรวม
1. บันทึกพื้นที่หน่วยความจำ: ค่าคงที่สตริงทั้งหมดที่มีค่าตัวอักษรเดียวกันในสระคงที่จะถูกรวมเข้าด้วยกัน
2. บันทึกเวลารัน: เมื่อทำการเปรียบเทียบสตริง == เร็วกว่าเท่ากับ () สำหรับตัวแปรอ้างอิงสองตัวเพียงแค่ใช้ == เพื่อตรวจสอบว่าการอ้างอิงมีค่าเท่ากันหรือไม่ดังนั้นคุณสามารถพิจารณาได้ว่าค่าจริงเท่ากันหรือไม่
== ความหมายของชนิดข้อมูลพื้นฐานและการแสดงวัตถุนั้นแตกต่างกัน
สำหรับประเภทข้อมูลพื้นฐาน: == การเปรียบเทียบเป็นค่าของประเภทข้อมูลพื้นฐานสำหรับวัตถุ: == การเปรียบเทียบคือที่อยู่หน่วยความจำของวัตถุในหน่วยความจำ
8 คลาสข้อมูลพื้นฐานการห่อหุ้มและพูลคงที่
คลาส wrapper ส่วนใหญ่ของประเภทข้อมูลพื้นฐานใน Java ใช้เทคโนโลยีการรวมอย่างต่อเนื่องคือไบต์, สั้น, จำนวนเต็ม, ยาว, ตัวละครและบูลีน
จำนวนเต็ม i1 = 40; จำนวนเต็ม i2 = 40; System.out.println (i1 == i2); // true
ไบต์, สั้น, จำนวนเต็ม, ยาว, อักขระ, คลาส wrapper ทั้งห้านี้สร้างข้อมูลแคชของประเภทที่สอดคล้องกันของ [-128, 127] โดยค่าเริ่มต้นและเก็บไว้ในพูลคงที่ หากเกินช่วงนี้วัตถุใหม่จะยังคงถูกสร้างขึ้น
ค่าคงที่ของจำนวนเต็มสาธารณะ (int i) {ยืนยัน IntegerCache.high> = 127; if (i> = integercache.low && i <= integercache.high) return integercache.cache [i + (-integercache.low)]; ส่งคืนจำนวนเต็มใหม่ (i); -จำนวนเต็ม i1 = 400; จำนวนเต็ม i2 = 400; System.out.println (i1 == i2); // false
2. คลาสบรรจุภัณฑ์หมายเลขลอยสองประเภทลอยตัวและสองเท่าไม่ใช้เทคโนโลยีการรวมการรวมกันอย่างต่อเนื่อง
double d1 = 2.5; double d2 = 2.5; System.out.println (d1 == d2); // false
3. สถานการณ์สำหรับการใช้พูลคงที่
(1) .Integeri1 = 40; เนื่องจากจำนวนเต็มเป็นคลาส wrapper ของประเภทข้อมูลพื้นฐาน int และเป็นวัตถุ java จะดำเนินการชกมวยอัตโนมัติเมื่อรวบรวมและห่อหุ้มรหัสลงใน Integeri1 = integer.valueof (40) โดยตรงจึงใช้วัตถุในพูลคงที่คงที่
(2) .integeri1 = Newinteger (40); ในกรณีนี้จะมีการสร้างวัตถุใหม่
จำนวนเต็ม i1 = 40; จำนวนเต็ม i2 = จำนวนเต็มใหม่ (40); System.out.println (i1 == i2); // false
ในกรณีนี้จำนวนเต็มใหม่จะไม่ดำเนินการอ้างอิงการชกมวยอัตโนมัติค่าคงที่ที่มีอยู่ในพูลคงที่ แต่จะสร้างวัตถุใหม่โดยตรงในฮีป
4. รายละเอียดจำนวนเต็ม
จำนวนเต็ม i1 = 40; จำนวนเต็ม i2 = 40; จำนวนเต็ม i3 = 0; จำนวนเต็ม i4 = จำนวนเต็มใหม่ (40); จำนวนเต็ม i5 = จำนวนเต็มใหม่ (40); จำนวนเต็ม i6 = จำนวนเต็มใหม่ (0); จำนวนเต็ม i7 = 128; จำนวนเต็ม i8 = 128; System.out.println ("i1 = i2" + (i1 == i2)); System.out.println ("i1 = i2 + i3" + (i1 == i2 + i3)); System.out.println ("i1 = i4" + (i1 == i4)); System.out.println ("i4 = i5" + (i4 == i5)); System.out.println ("i4 = i5 + i6" + (i4 == i5 + i6)); System.out.println ("40 = i5 + i6" + (40 == i5 + i6)); System.out.println ("i7 = i8" + (i7 == i8));i1 = i2 truei1 = i2+i3 truei1 = i4 falsei4 = i5 falsei4 = i5+i6 true40 = i5+i6 truei7 = i8 false
คำอธิบาย: คำสั่ง i4 == i5 + i6 เนื่องจากตัวดำเนินการ + ไม่สามารถใช้ได้กับวัตถุจำนวนเต็ม ก่อนอื่น i5 และ i6 ทำการดำเนินการ Unboxing อัตโนมัติและเพิ่มค่านั่นคือ I4 == 40 จากนั้นวัตถุจำนวนเต็มไม่สามารถเปรียบเทียบได้โดยตรงกับค่าตัวเลขดังนั้น i4 จึงยกเลิกกล่องและแปลงเป็นค่า int 40 โดยอัตโนมัติในที่สุดคำสั่งนี้จะถูกแปลงเป็น 40 == 40 สำหรับการเปรียบเทียบเชิงตัวเลข
คลาสสตริงและพูลคงที่
1. สร้างวัตถุสตริงได้อย่างไร
String S1 = "ABDCD"; String S2 = String ใหม่ ("ABCD"); System.out.println (S1 == S2); // falseมีความแตกต่างในวิธีการสร้างของสองวิธีที่แตกต่างกันนี้ สิ่งแรกคือการใช้วัตถุในพูลคงที่และที่สองคือการสร้างวัตถุใหม่ในพื้นที่หน่วยความจำฮีป
เพียงแค่ใช้วัตถุใหม่จะถูกสร้างขึ้นในกอง
2. นิพจน์การเชื่อมต่อ+
(1). เฉพาะวัตถุใหม่ที่สร้างขึ้นโดยการเชื่อมต่อ "+" ระหว่างวัตถุสตริงที่สร้างขึ้นโดยใช้ข้อความ "" ที่มีข้อความจะถูกเพิ่มลงในพูลคงที่สตริง
(2). สำหรับรูปแบบอื่น ๆ เช่นการอ้างอิงวัตถุสองรายการที่เชื่อมต่อโดยตรงผ่าน "+" หรือวัตถุที่สร้างขึ้นผ่านโหมดใหม่วัตถุใหม่ที่ได้จะไม่ถูกเพิ่มลงในพูลคงที่สตริง
string str1 = "str"; string str2 = "ing"; string str3 = "str" + "ing"; string str4 = str1 + str2; system.out.println (str3 == str4); // string false str5 = "string"; system.out.println (str3 == str5);
สตริงสุดท้ายคงที่สาธารณะ A = "AB"; // ค่าคงที่ apublic คงที่สตริงสุดท้าย b = "cd"; // ค่าคงที่ bpublic static void main (string [] args) {string s = a + b; // เริ่มต้น s ด้วย + การเชื่อมต่อสตริง t = "abcd"; if (s == t) {system.out.println ("S เท่ากับ t พวกเขาเป็นวัตถุเดียวกัน"); } else {system.out.println ("s ไม่เท่ากับ t พวกเขาไม่ใช่วัตถุเดียวกัน"); }} S เท่ากับ t พวกมันเป็นวัตถุเดียวกันA และ B เป็นทั้งค่าคงที่และค่าได้รับการแก้ไขดังนั้นค่าของ S ได้รับการแก้ไขซึ่งจะถูกกำหนดเมื่อรวบรวมคลาส กล่าวอีกนัยหนึ่ง: สตริง s = a+b; เทียบเท่ากับ: String S =” AB”+” CD”;
สตริงสุดท้ายคงที่สาธารณะ A; // ค่าคงที่ apublic คงที่สตริง b; // ค่าคงที่ bstatic {a = "ab"; b = "cd"; } โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// เริ่มต้น s ด้วย + การเชื่อมต่อสตริง s = a + b; สตริง t = "abcd"; if (s == t) {system.out.println ("S เท่ากับ t พวกเขาเป็นวัตถุเดียวกัน"); } else {system.out.println ("s ไม่เท่ากับ t พวกเขาไม่ใช่วัตถุเดียวกัน"); }} s ไม่เท่ากับ t พวกเขาไม่ใช่วัตถุเดียวกันแม้ว่า A และ B ถูกกำหนดเป็นค่าคงที่ แต่ก็ไม่ได้รับมอบหมายทันที ก่อนที่จะคำนวณค่าของ S เมื่อได้รับมอบหมายและค่าที่กำหนดไว้คือตัวแปร ดังนั้นก่อนที่ A และ B จะได้รับมอบหมายคุณสมบัติของพวกเขาจะคล้ายกับตัวแปร จากนั้น S ไม่สามารถกำหนดได้ในช่วงระยะเวลาการรวบรวม แต่สามารถสร้างได้เมื่อรันไทม์เท่านั้น
3.strings1 = newstring ("xyz"); มีการสร้างวัตถุกี่ชิ้น?
พิจารณาขั้นตอนการโหลดคลาสและการดำเนินการจริง
(1) การโหลดคลาสจะดำเนินการเพียงครั้งเดียวในชั้นเรียน "XYZ" ถูกสร้างขึ้นและอาศัยอยู่เมื่อมีการโหลดคลาส (ถ้าสตริง "XYZ" ได้รับการอาศัยก่อนที่คลาสจะถูกโหลดไม่จำเป็นต้องสร้างอินสแตนซ์ "XYZ" ซ้ำ ๆ ) สตริงที่อยู่อาศัยจะถูกวางไว้ในพูลคงที่สตริงที่ใช้ร่วมกันทั่วโลก
(2) เมื่อรหัสนี้ทำงานในภายหลังอินสแตนซ์สตริงที่สอดคล้องกับตัวอักษร "XYZ" ได้รับการแก้ไขและจะไม่ถูกสร้างซ้ำ ๆ ดังนั้นรหัสนี้จะคัดลอกสำเนาของวัตถุในพูลคงที่และวางลงในกองและส่งการอ้างอิงไปยังวัตถุในกองถึง S1 เพื่อถือ
คำสั่งนี้สร้าง 2 วัตถุ
4.Java.lang.string.intern ()
คุณสมบัติที่สำคัญอีกประการหนึ่งของพูลคงที่รันไทม์เมื่อเทียบกับพูลคงที่ไฟล์คลาสคือไดนามิก ภาษา Java ไม่จำเป็นต้องมีค่าคงที่เฉพาะในช่วงระยะเวลาการรวบรวมนั่นคือเนื้อหาของพูลคงที่ในไฟล์คลาสสามารถเข้าสู่พื้นที่วิธีการ ค่าคงที่ใหม่อาจถูกวางลงในสระว่ายน้ำในช่วงเวลา คุณลักษณะนี้ใช้กันทั่วไปโดยนักพัฒนา วิธีการฝึกงาน () ของคลาสสตริง
วิธีการฝึกงาน () ของสตริงจะค้นหาว่ามีสตริงที่เท่ากันเท่ากันในพูลคงที่หรือไม่ หากมีมันจะส่งคืนการอ้างอิงไปยังสตริง หากไม่มีมันจะเพิ่มสตริงของตัวเองลงในพูลคงที่
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {สตริง s1 = สตริงใหม่ ("คอมพิวเตอร์"); สตริง s2 = s1.intern (); สตริง s3 = "คอมพิวเตอร์"; System.out.println ("S1 == S2?" + (S1 == S2)); System.out.println ("S3 == S2?" + (S3 == S2));}S1 == S2? Falses3 == S2? จริง
สรุป
ข้างต้นคือทั้งหมดที่เกี่ยวกับการสำรวจสระว่ายน้ำคงที่ Java ในเชิงลึก ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น