CodeGym /จาวาบล็อก /สุ่ม /10 สิ่งที่คุณต้องรู้เกี่ยวกับ Static Modifier ใน Java
John Squirrels
ระดับ
San Francisco

10 สิ่งที่คุณต้องรู้เกี่ยวกับ Static Modifier ใน Java

เผยแพร่ในกลุ่ม
ใน Java ตัวดัดแปลงแบบสแตติกหมายถึงบางสิ่งที่เกี่ยวข้องโดยตรงกับคลาส: ถ้าฟิลด์เป็นแบบสแตติก แสดงว่าเป็นของคลาส หากเมธอดเป็นแบบสแตติก แสดงว่าเป็นของคลาส ด้วยเหตุนี้ คุณสามารถใช้ชื่อของคลาสเพื่อเรียกเมธอดสแตติกหรืออ้างอิงฟิลด์สแตติก ตัวอย่างเช่น ถ้าcountฟิลด์เป็นแบบคงที่ในCounterคลาส หมายความว่าคุณสามารถอ้างอิงตัวแปรด้วยนิพจน์ต่อไปนี้Counter.count: 10 สิ่งที่คุณต้องรู้เกี่ยวกับ Static Modifier ใน Java - 1แน่นอนว่าต้องพิจารณาตัวดัดแปลงการเข้าถึง ตัวอย่างเช่นprivateฟิลด์จะพร้อมใช้งานภายในคลาสที่มีการประกาศเท่านั้น และprotectedฟิลด์จะพร้อมใช้งานสำหรับทุกคลาสภายในแพ็คเกจ เช่นเดียวกับคลาสย่อยทั้งหมดที่อยู่นอกแพ็คเกจ สมมติว่าCounterคลาสมีincrement()เมธอดแบบสแตติกซึ่งมีหน้าที่เพิ่มค่าcountสนาม. ในการเรียกใช้เมธอดนี้ คุณสามารถใช้Counter.increment(). ไม่จำเป็นต้องสร้างอินสแตนซ์ของCounterคลาสเพื่อเข้าถึงฟิลด์หรือเมธอดแบบสแตติก นี่คือความแตกต่างพื้นฐานระหว่างตัวแปรและเมธอดแบบสแตติก (คลาส) และตัวแปรและเมธอดแบบไม่คงที่ (อินสแตนซ์) หมายเหตุสำคัญ อย่าลืมว่าสมาชิกคงที่ของคลาสเป็นของคลาสโดยตรง ไม่ใช่ตัวอย่างใดๆ ของคลาส นั่นคือค่าของตัวแปรคงcountที่จะเหมือนกันสำหรับCounterวัตถุ ทั้งหมด ในบทความนี้ เราจะพิจารณาลักษณะพื้นฐานของการใช้สแตติกโมดิฟายเออร์ใน Java รวมถึงคุณสมบัติบางอย่างที่จะช่วยให้คุณเข้าใจแนวคิดหลักในการเขียนโปรแกรม

สิ่งที่โปรแกรมเมอร์ทุกคนควรรู้เกี่ยวกับ Static Modifier ใน Java

ในส่วนนี้ เราจะพิจารณาประเด็นหลักของการใช้เมธอด ฟิลด์ และคลาสแบบสแตติก เริ่มจากตัวแปรกันก่อน
  1. คุณไม่สามารถเข้าถึงสมาชิกที่ไม่ใช่สแตติกของคลาสภายในบริบทสแตติก เช่น เมธอดหรือบล็อกสแตติก การคอมไพล์โค้ดด้านล่างจะทำให้เกิดข้อผิดพลาด:

    
    public class Counter {
    private int count;
    public static void main(String args []) {
       System.out.println(count); //  Compile time error
    }
    }
    

    นี่เป็นข้อผิดพลาดที่พบบ่อยที่สุดอย่างหนึ่งของโปรแกรมเมอร์ Java โดยเฉพาะมือใหม่ เนื่องจากmainเมธอดเป็นแบบสแตติกและcountไม่ใช่ตัวแปร การใช้printlnเมธอดภายในmainเมธอดจะทำให้เกิด "ข้อผิดพลาดในการคอมไพล์"

  2. ไม่เหมือนกับตัวแปรโลคัล ฟิลด์สแตติกและเมธอดไม่มีthread safeใน Java ในทางปฏิบัติ นี่เป็นหนึ่งในสาเหตุที่พบบ่อยที่สุดของปัญหาด้านความปลอดภัยในการเขียนโปรแกรมแบบมัลติเธรด เมื่อพิจารณาว่าแต่ละอินสแตนซ์ของคลาสอ้างอิงสำเนาเดียวกันของตัวแปรสแตติก ตัวแปรดังกล่าวจำเป็นต้องได้รับการป้องกันหรือ "ล็อค" โดยคลาส ดังนั้น เมื่อใช้ตัวแปรสแต ติกต้องแน่ใจว่าถูกต้องsynchronizedเพื่อหลีกเลี่ยงปัญหา เช่นrace conditions

  3. เมธอดแบบสแตติกมีข้อได้เปรียบในทางปฏิบัติตรงที่ไม่จำเป็นต้องสร้างออบเจกต์ใหม่ทุกครั้งที่คุณต้องการเรียกใช้ สามารถเรียกใช้เมธอดแบบสแตติกได้โดยใช้ชื่อของคลาสที่ประกาศ นั่นเป็นเหตุผลที่วิธีการเหล่านี้เหมาะสำหรับfactoryวิธีการและutilityวิธีการต่างๆ คลาส นี้java.lang.Mathเป็นตัวอย่างที่ยอดเยี่ยม: เมธอดเกือบทั้งหมดเป็นแบบสแตติก คลาสยูทิลิตี้ของ Java ถูกทำเครื่องหมายfinalด้วยเหตุผลเดียวกัน

  4. จุดสำคัญอีกประการหนึ่งคือคุณไม่สามารถแทนที่ ( @Override) เมธอดแบบสแตติกได้ หากคุณประกาศเมธอดดังกล่าวใน a subclassคือเมธอดที่มีชื่อและลายเซ็นเดียวกัน คุณเพียงแค่ "ซ่อน" เมธอดของ the superclassแทนที่จะแทนที่เมธอดนั้น ปรากฏการณ์นี้เรียกmethod hidingว่า ซึ่งหมายความว่าหากมีการประกาศเมธอดสแตติกทั้งในคลาสพาเรนต์และคลาสย่อย เมธอดที่เรียกจะขึ้นอยู่กับประเภทตัวแปรเสมอในเวลาคอมไพล์ ซึ่งแตกต่างจากการแทนที่เมธอด เมธอดดังกล่าวจะไม่ทำงานเมื่อโปรแกรมทำงาน ลองพิจารณาตัวอย่าง:

    
    class Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the parent class / static method");
         } 
    }
    
    class Car extends Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the child class / static method");
         } 
    }
    
    public class Demo {   
       public static void main(String args []) {
          Vehicle v = new Car();
           v.kmToMiles(10);
      }
    }
    

    เอาต์พุตคอนโซล:

    ภายในคลาสพาเรนต์ / เมธอดสแตติก

    รหัสแสดงให้เห็นอย่างชัดเจนว่าแม้ว่าวัตถุจะเป็น a ก็ตามCarวิธีการแบบสแตติกในVehicleคลาสนั้นถูกเรียก เนื่องจากเมธอดถูกเรียกในเวลาคอมไพล์ และโปรดทราบว่าไม่มีข้อผิดพลาดในการรวบรวม!

  5. ยิ่งไปกว่านั้น นอกจากคลาสระดับบนสุดแล้ว คุณสามารถประกาศคลาสแบบสแตติกได้ คลาสดังกล่าวเรียกnested static classesว่า พวกมันมีประโยชน์สำหรับการประสานกันที่ดีขึ้น ตัวอย่างที่โดดเด่นของคลาสสแตติกที่ซ้อนกันคือHashMap.Entryซึ่งเป็นโครงสร้างข้อมูลHashMapภายใน เป็นที่น่าสังเกตว่าเช่นเดียวกับคลาสภายใน คลาสที่ซ้อนกันแบบสแตติกจะถูกประกาศในไฟล์ .class แยกต่างหาก ดังนั้น หากคุณประกาศคลาสที่ซ้อนกัน 5 คลาสในคลาสหลัก คุณจะมีไฟล์ 6 ไฟล์ที่มีนามสกุล .class อีกตัวอย่างหนึ่งคือการประกาศของเราเองComparatorเช่น ตัวเปรียบเทียบอายุ ( AgeComparator) ในEmployeeชั้นเรียน

  6. นอกจากนี้ยังสามารถระบุตัวดัดแปลงแบบคงที่ในบล็อกแบบคงที่หรือที่รู้จักกันดีในชื่อ "บล็อกการกำหนดค่าเริ่มต้นแบบคงที่" ซึ่งจะดำเนินการเมื่อโหลดคลาส หากคุณไม่ประกาศบล็อกดังกล่าว Java จะรวบรวมฟิลด์สแตติกทั้งหมดไว้ในรายการเดียวและเริ่มต้นเมื่อคลาสถูกโหลด บล็อกแบบคงที่ไม่สามารถโยนข้อยกเว้นที่ตรวจสอบได้ แต่สามารถโยนข้อยกเว้นที่ไม่ได้ตรวจสอบได้ ในกรณีนี้ExceptionInInitializerErrorจะเกิดขึ้น ในทางปฏิบัติ ข้อยกเว้นใดๆ ที่เกิดขึ้นระหว่างการเริ่มต้นของฟิลด์สแตติกจะถูกรวมไว้ในข้อผิดพลาดนี้โดย Java นี่เป็นสาเหตุที่พบบ่อยที่สุดของNoClassDefFoundErrorเนื่องจากคลาสจะไม่อยู่ในหน่วยความจำเมื่อมีการอ้างอิง

  7. การรู้ว่าเมธอดสแตติกถูกเชื่อมโยงในเวลาคอมไพล์ ซึ่งต่างจากการลิงก์เมธอดเสมือนหรือไม่ใช่สแตติก ซึ่งจะเชื่อมโยงในขณะรันเมื่อเรียกบนอ็อบเจกต์จริง มีประโยชน์ ดังนั้นจึงไม่สามารถแทนที่เมธอดสแตติกใน Java ได้ เนื่องจากโพลิมอร์ฟิซึมไม่ได้ใช้กับเมธอดเหล่านี้ในขณะรันไทม์ นี่เป็นข้อจำกัดที่สำคัญที่ต้องพิจารณาเมื่อประกาศเมธอดสแตติก การทำเช่นนั้นสมเหตุสมผลก็ต่อเมื่อไม่มีความสามารถหรือจำเป็นต้องแทนที่เมธอดในคลาสย่อย วิธีการจากโรงงานและวิธีการยูทิลิตี้เป็นตัวอย่างที่ดีของการใช้ตัวแก้ไขแบบคงที่อย่างเหมาะสม Joshua Blochชี้ให้เห็นข้อดีหลายประการที่วิธีการแบบโรงงานแบบคงที่มีมากกว่าตัวสร้างในหนังสือ Java ของเขาที่มีประสิทธิภาพ ซึ่งเป็นข้อบังคับสำหรับโปรแกรมเมอร์ Java ทุกคน

  8. การเริ่มต้นเป็นสิ่งสำคัญของบล็อกแบบคงที่ ฟิลด์หรือตัวแปรสแตติกจะถูกเตรียมใช้งานหลังจากโหลดคลาสลงในหน่วยความจำ ลำดับของการเริ่มต้นคือจากบนลงล่าง ตามลำดับเดียวกับที่ประกาศไว้ในซอร์สไฟล์ของคลาส Java เนื่องจากฟิลด์สแตติกถูกเตรียมใช้งานในลักษณะที่ปลอดภัยสำหรับเธรด กระบวนการนี้จึงถูกใช้เพื่อนำSingletonรูปแบบ ไปใช้ด้วย หากคุณไม่ได้ใช้ an Enumด้วยSingletonเหตุผลบางประการ แสดงว่าคุณมีทางเลือกอื่นที่ดี แต่ในกรณีนี้ คุณต้องคำนึงว่านี่ไม่ใช่การเริ่มต้นที่ "ขี้เกียจ" ซึ่งหมายความว่าฟิลด์สแตติกจะเริ่มต้นได้ก่อนที่จะมีคน "ขอ" ให้ หากออบเจกต์ใช้ทรัพยากรจำนวนมากหรือไม่ค่อยได้ใช้ การเริ่มต้นวัตถุนั้นในบล็อกแบบสแตติกจะไม่เป็นประโยชน์กับคุณ

  9. ในระหว่างการทำให้เป็นอนุกรม ฟิลด์สแตติก เช่นtransientตัวแปร จะไม่ถูกทำให้เป็นอนุกรม แน่นอน หากคุณบันทึกข้อมูลใดๆ ลงในฟิลด์สแตติก ข้อมูลนั้นจะมีค่าเริ่มต้น (ดีฟอลต์) หลังจากดีซีเรียลไลเซชัน ตัวอย่างเช่น ถ้าฟิลด์สแตติกเป็น ค่าintของฟิลด์นั้นจะเป็นศูนย์หลังจากการดีซีเรียลไลเซชัน หากเป็นประเภทfloatค่าจะเป็น 0.0 ถ้าฟิลด์เป็น an Objectค่าจะnullเป็น พูดตามตรง นี่เป็นคำถามที่พบบ่อยที่สุดคำถามหนึ่งเกี่ยวกับการออกหมายเลขกำกับในการสัมภาษณ์ตำแหน่งงาน Java อย่าเก็บข้อมูลอ็อบเจกต์ที่จำเป็นในฟิลด์คงที่!

  10. สุดท้ายเรามาพูดถึงการนำเข้าแบบคงที่ โมดิฟายเออร์นี้มีหลายอย่างที่เหมือนกันกับimportคำสั่งมาตรฐาน แต่จะแตกต่างกันตรงที่อนุญาตให้คุณนำเข้าสมาชิกคลาสสแตติกหนึ่งหรือทั้งหมด เมื่ออิมพอร์ตเมธอดสแตติกแล้ว จะสามารถเข้าถึงได้เหมือนกับว่าประกาศไว้ในคลาสเดียวกัน ในทำนองเดียวกัน โดยการนำเข้าฟิลด์สแตติก เราสามารถเข้าถึงได้โดยไม่ต้องระบุชื่อคลาส คุณลักษณะนี้ปรากฏใน Java 1.5 และปรับปรุงการอ่านรหัสเมื่อใช้อย่างถูกต้อง โครงสร้างนี้พบบ่อยที่สุดในการทดสอบ JUnit เนื่องจากผู้พัฒนาทดสอบเกือบทั้งหมดใช้การนำเข้าแบบคงที่สำหรับวิธีการยืนยัน เช่นassertEquals()และตัวแปรที่โอเวอร์โหลด

  11. นั่นคือทั้งหมดที่สำหรับตอนนี้. โปรแกรมเมอร์ Java ทุกคนจำเป็นต้องรู้ทุกแง่มุมของสแตติกโมดิฟายเออร์ที่กล่าวถึงข้างต้น บทความนี้ทบทวนข้อมูลพื้นฐานเกี่ยวกับตัวแปรคงที่ ฟิลด์ วิธีการ บล็อกการเริ่มต้น และการนำเข้า นอกจากนี้ยังกล่าวถึงคุณสมบัติที่สำคัญบางอย่างที่จำเป็นในการเขียนและทำความเข้าใจโปรแกรม Java ฉันหวังว่านักพัฒนาซอฟต์แวร์ทุกคนจะใช้สมาชิกแบบคงที่อย่างมีทักษะได้อย่างสมบูรณ์แบบ เพราะมันสำคัญมากสำหรับการพัฒนาซอฟต์แวร์อย่างจริงจัง"

ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION