บทความนี้ส่วนใหญ่ศึกษาปัญหาของการสร้างวัตถุในสตริง Java ดังต่อไปนี้
ก่อนอื่นเราต้องเข้าใจสองแนวคิด: การอ้างอิงตัวแปรและวัตถุ โดยทั่วไปวัตถุจะถูกสร้างขึ้นในกองผ่านใหม่และสตริงเป็นเพียงตัวแปรอ้างอิง
สตริงทั้งหมดเป็นวัตถุสตริง เนื่องจากการใช้จ่ายสตริงจำนวนมากเพื่อประหยัดเวลาใน Java ในขั้นตอนการรวบรวมค่าคงที่สตริงทั้งหมดจะถูกวางไว้ในพูลคงที่สตริง ข้อดีอย่างหนึ่งของพูลคงที่สตริงคือสตริงเดียวกันสามารถรวมและครอบครองพื้นที่
แม้ว่าที่อยู่ของตัวแปรไม่สามารถได้รับโดยตรงใน Java คุณสามารถใช้ == เพื่อตรวจสอบว่าตัวแปรอ้างอิงทั้งสองชี้ไปที่ที่อยู่นั่นคือวัตถุ
| หน่วยความจำกอง | หน่วยความจำกอง |
|---|---|
| ประเภทพื้นฐานการอ้างอิงวัตถุ (ที่อยู่หน่วยความจำฮีป) | วัตถุและอาร์เรย์ที่สร้างขึ้นโดยใหม่ |
| ความเร็วในการเข้าถึงที่รวดเร็ว | หน่วยความจำช้ากว่าสแต็ก |
| ต้องกำหนดขนาดข้อมูลในระหว่างรอบการประกาศ | หน่วยความจำที่จัดสรรได้รับการจัดการโดยเครื่องเก็บขยะอัตโนมัติ Java Virtual Machine ขนาดหน่วยความจำที่จัดสรรแบบไดนามิก |
| คุณสมบัติที่ใช้ร่วมกันหากมีสตริงในสแต็กจะมีการอ้างอิงโดยตรง ถ้าไม่เปิดพื้นที่ใหม่เพื่อจัดเก็บค่า | ใหม่ทุกคนสร้างวัตถุใหม่ในหน่วยความจำฮีป ไม่มีการใช้ซ้ำ |
แพ็คเกจ com.demo.test; นำเข้า java.lang.reflect.field; คลาสสาธารณะ StringDemo {โมฆะสาธารณะคงที่หลัก (String [] args) {// ก่อนดูว่าวัตถุสตริงนี้มีอยู่ในหน่วยความจำหรือไม่ หากมีอยู่ให้ชี้ไปที่วัตถุสตริงนี้ string str1 = "abc"; string str2 = "abc"; /* สตริงสาธารณะ toString () {ส่งคืนสิ่งนี้; } */ string str3 = "abc" .toString (); // ไม่ว่าวัตถุสตริงนี้จะมีอยู่ในหน่วยความจำแล้ววัตถุใหม่จะถูกสร้างขึ้น string str4 = สตริงใหม่ ("abc"); string str5 = สตริงใหม่ ("abc"); string str6 = str5; string str7 = "a" + "b" + "c"; String str8 = "A" + "B" + สตริงใหม่ ("C"); // string เป็นวัตถุสตริงที่ไม่เปลี่ยนรูป stringbuilder และ stringbuffer เป็นวัตถุสตริงตัวแปร (ความยาวของอาร์เรย์อักขระภายในเป็นตัวแปร), stringbuffer คือ thread-safe, stringbuilder ไม่ใช่ String-Safe String str9 = StringBuilder ใหม่ () string str10 = ใหม่ stringbuffer (). ผนวก ("a"). ผนวก ("b"). ผนวก ("c"). toString (); System.out.println ("---------> =="); System.out.println ("---> 1"); System.out.println (str1 == str2); // true system.out.println ("---> 3"); System.out.println (str3 == str1); // true system.out.println ("-> 4"); System.out.println (str4 == str1); // false system.out.println (str4 == str3); // false system.out.println (str4 == str5); // false system.out.println (str4 == str6); // ระบบเท็จ System.out.println (str7 == str1); // true system.out.println (str7 == str3); // true system.out.println (str7 == str4); // talse system.out.println ("---> 8"); System.out.println (str8 == str1); // false system.out.println (str8 == str3); // false system.out.println (str8 == str4); // false system.out.println (str8 == str7); // ระบบเท็จ System.out.println (str9 == str1); // false system.out.println (str9 == str3); // talse system.out.println (str9 == str4); // talse system.out.println (str9 == str7); // ระบบเท็จ. System.out.println (str10 == str1); // false system.out.println (str10 == str3); // false system.out.println (str10 == str4); // talse system.out.println (str10 == str7); System.out.println (str10 == str9); // false system.out.println ("--------> equals"); System.out.println (str1.equals (str4)); // true system.out.println (str1.equals (str7)); // true system.out.println (str1.equals (str8)); /*สูตรการคำนวณ HashCode: S [0]*31^(N-1) + S [1]*31^(N-2) + ... + S [N-1] ดังนั้น HashCode จะเหมือนกันและมันก็เหมือนกันทุกครั้งที่มันทำงาน*/System.out.println System.out.println (str3.hashcode ()); System.out.println (str4.hashcode ()); System.out.println (str5.HashCode ()); System.out.println (str6.hashcode ()); System.out.println (str7.hashcode ()); System.out.println ("--------> ค่าการเปลี่ยนแปลงปกติ"); // สตริงเป็นคลาสที่ไม่เปลี่ยนรูป สตริงชี้ไปที่การอ้างอิงในหน่วยความจำฮีปเท่านั้น มันเก็บที่อยู่ของวัตถุในกองไม่ใช่วัตถุเอง การกำหนดค่าให้กับสตริงคือการเปลี่ยนวัตถุอ้างอิงแทนวัตถุเอง str6 = "123"; System.out.println (str5); // abc system.out.println (str6); // 123 system.out.println ("--------> สะท้อนค่าการเปลี่ยนแปลง"); /* หากคุณต้องเปลี่ยนค่าของสตริงมันก็เป็นไปไม่ได้ สามารถใช้งานได้เท่านั้น สตริงคลาสสุดท้ายของสาธารณะใช้ java.io.serializable, เทียบเท่า <string>, charsequence {// ค่าที่ใช้สำหรับการจัดเก็บอักขระ ค่าถ่านสุดท้ายส่วนตัว []; …} */ str6 = str5; ลอง {ฟิลด์ฟิลด์ = string.class.getDeclaredField ("value"); // ฟิลด์ฟิลด์ = str6.getClass (). getDeclaredField ("value"); if (! field.isaccessible ()) {field.setAccessible (จริง); } char [] value = (char []) field.get (str6); ค่า [0] = '0'; System.out.println (str5); // 0bc system.out.println (str6); // 0bc} catch (nosuchfieldexception | SecurityException | unlegalArgumentException | ungleclAccessException e) {e.printstacktrace (); } system.out.println ("-------> obj.toString ()"); Object OBJ = วัตถุใหม่ (); /* สตริงสาธารณะ toString () {return getClass (). getName () + "@" + integer.toHexstring (hashCode ()); } */system.out.println (obj.toString ()); // java.lang.object@15db9742 String [] arr1 = {"0"}; สตริง [] arr2 = {"0"}; System.out.println (arr1.equals (arr2)); // false}}สรุป
ข้างต้นคือทั้งหมดที่เกี่ยวกับการวิเคราะห์อินสแตนซ์วัตถุการสร้างสตริง Java และฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!