นี่เป็นบทความที่ดีที่ให้เหตุผลสองประการที่กล่าวถึงแล้วในคำตอบข้างต้น:
- ความปลอดภัย : ระบบสามารถแจกบิตที่ละเอียดอ่อนของข้อมูลแบบอ่านอย่างเดียวโดยไม่ต้องกังวลว่าจะมีการเปลี่ยนแปลง
- ประสิทธิภาพการทำงาน : ข้อมูลที่ไม่เปลี่ยนรูปนั้นมีประโยชน์มากในการทำสิ่งต่าง ๆ ให้ปลอดภัยต่อเธรด
และนี่อาจเป็นความคิดเห็นที่ละเอียดที่สุดในบทความนั้น มันเกี่ยวกับสตริงพูลใน Java และปัญหาด้านความปลอดภัย มันเกี่ยวกับวิธีการตัดสินใจสิ่งที่จะเข้าสู่สระว่ายน้ำสตริง สมมติว่าสตริงทั้งสองมีค่าเท่ากันหากลำดับของอักขระเหมือนกันเรามีเงื่อนไขการแข่งขันว่าใครมาถึงที่นั่นก่อนและพร้อมด้วยปัญหาด้านความปลอดภัย ถ้าไม่เช่นนั้นพูลสตริงจะมีสตริงซ้ำซ้อนจึงสูญเสียความได้เปรียบจากการมีสตริงนั้นในตอนแรก แค่อ่านด้วยตัวเองใช่มั้ย
การขยายสตริงจะเล่นความเสียหายด้วยเท่ากับและฝึกงาน JavaDoc พูดว่าเท่ากับ:
เปรียบเทียบสตริงนี้กับวัตถุที่ระบุ ผลลัพธ์จะเป็นจริงถ้าอาร์กิวเมนต์นั้นไม่ใช่โมฆะและเป็นวัตถุสตริงที่แสดงถึงลำดับของอักขระเช่นเดียวกับวัตถุนี้
การสันนิษฐานว่าjava.lang.String
ยังไม่ถึงขั้นสุดท้าย a SafeString
อาจเท่ากับString
และในทางกลับกัน เพราะพวกเขาต้องการแสดงลำดับของอักขระที่เหมือนกัน
จะเกิดอะไรขึ้นถ้าคุณใช้intern
กับ a SafeString
- การSafeString
เข้าไปในสตริงพูลของ JVM หรือไม่ ClassLoader
และทุกวัตถุSafeString
อ้างอิงที่จัดขึ้นเพื่อจากนั้นก็จะได้รับการถูกขังอยู่ในสถานที่สำหรับอายุการใช้งานของ JVM คุณจะได้รับเงื่อนไขการแข่งขันว่าใครจะเป็นคนแรกที่จะเรียงลำดับของตัวละคร - บางทีคุณอาจSafeString
จะชนะอาจจะString
หรือSafeString
โหลดโดย classloader ที่แตกต่างกัน
หากคุณชนะการแข่งขันในสระว่ายน้ำนี่จะเป็นซิงเกิลที่แท้จริงและผู้คนสามารถเข้าถึงสภาพแวดล้อมทั้งหมดของคุณผ่านทางภาพสะท้อนและ secretKey.intern().getClass().getClassLoader()
ผ่านการสะท้อนและการ
หรือ JVM สามารถบล็อกหลุมนี้ได้โดยตรวจสอบให้แน่ใจว่ามีการเพิ่มเฉพาะวัตถุ String String (และไม่มีคลาสย่อย) ในพูล
หากมีการใช้งานเท่ากับนั้น SafeString
!! = String
แล้วSafeString.intern
! = String.intern
และSafeString
จะต้องเพิ่มลงในพูล สระว่ายน้ำก็จะกลายเป็นสระว่ายน้ำ<Class, String>
แทน<String>
และสิ่งที่คุณต้องใช้ในการเข้าร่วมสระว่ายน้ำจะเป็น classloader ที่สดใหม่