ทำไมต้องใช้ตัวโหลดคลาส?
ในภาษา Java การโหลดคลาสจะเสร็จสมบูรณ์ในระหว่างการดำเนินการโปรแกรม แม้ว่ากลยุทธ์นี้จะเพิ่มประสิทธิภาพการทำงานเล็กน้อยเมื่อโหลดคลาส แต่จะให้แอพพลิเคชั่น Java มีความยืดหยุ่นในระดับสูง ตัวอย่างเช่น:
1. เขียนแอปพลิเคชันที่เน้นอินเทอร์เฟซและอาจรอจนกว่าจะทำงานก่อนที่จะระบุคลาสย่อยการใช้งาน
2. ผู้ใช้สามารถปรับแต่งคลาสโหลดเดอร์ทำให้โปรแกรมสามารถโหลดสตรีมไบนารีจากเครือข่ายหรือสถานที่อื่น ๆ ซึ่งเป็นส่วนหนึ่งของรหัสโปรแกรมที่รันไทม์ (นี่คือพื้นฐานสำหรับปลั๊กอิน Android การติดตั้งแบบไดนามิกและการอัปเดต APK)
ทำไมต้องศึกษากระบวนการทั้งหมดของการโหลดในชั้นเรียน?
กลไกการโหลดคลาส
JVM โหลดไฟล์คลาสลงในหน่วยความจำและตรวจสอบวิเคราะห์และเริ่มต้นข้อมูลและในที่สุดก็สร้างกระบวนการทั้งหมดของประเภท Java ที่ JVM สามารถใช้โดยตรง
โหลด
โหลดเนื้อหา bytecode ของไฟล์คลาสลงในหน่วยความจำและแปลงข้อมูลแบบคงที่เป็นโครงสร้างข้อมูลรันไทม์ในพื้นที่เมธอดและสร้าง java.lang.Class วัตถุคลาสที่เป็นตัวแทนของคลาสนี้ในฮีปเป็นพอร์ทัลการเข้าถึงสำหรับข้อมูลคลาสของเมธอด กระบวนการนี้ต้องมีการมีส่วนร่วมของตัวโหลดคลาส
การเชื่อมโยง
กระบวนการรวมรหัสไบนารีของคลาส Java เข้ากับสถานะการทำงานของ JVM
การเริ่มต้น
<clinit>() วิธีการสร้างคลาส <clinit>() ถูกสร้างขึ้นโดยคอมไพเลอร์รวบรวมการกระทำที่ได้รับมอบหมายของตัวแปรคลาสทั้งหมดในคลาสและการผสานของคำสั่งในบล็อกคำสั่งแบบคงที่ (บล็อกคงที่)<clinit>() ของชั้นเรียนถูกล็อคและซิงโครไนซ์อย่างถูกต้องในสภาพแวดล้อมแบบมัลติเธรดตัวอย่างที่ 1:
การสาธิตคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {a = new a (); System.out.println (A.Width); }} คลาส A {ความกว้าง int คงที่สาธารณะ = 100; // ตัวแปรคงที่ฟิลด์ฟิลด์คงที่ {system.out.println ("การเริ่มต้นแบบคงที่คลาส A"); ความกว้าง = 300; } สาธารณะ a () {system.out.println ("สร้างวัตถุของคลาส A"); -วิเคราะห์:
ภาพประกอบ:
มีสแต็คกอง (สถานที่ที่สร้างขึ้น) และพื้นที่วิธีการในหน่วยความจำ (จริง ๆ เป็นกองพิเศษ)
1. เมื่อ JVM โหลด DEMO01 รูปแบบแรกของข้อมูลคงที่ (ตัวแปรคลาส, วิธีการคลาส, รหัส ... ) ในพื้นที่เมธอด ในเวลาเดียวกันวัตถุ java.lang.Class (วัตถุสะท้อนแสง) จะเกิดขึ้นในกองซึ่งเป็นตัวแทนของคลาส Demo01 ผ่านวัตถุสามารถเข้าถึงโครงสร้างไบนารีคลาสได้ จากนั้นโหลดข้อมูล Class A ตัวแปรและสร้างวัตถุ A ในฮีปแทนคลาส A.
2. เมื่อวิธีการหลักถูกดำเนินการเฟรมหลักวิธีหลักจะเกิดขึ้นในสแต็กและหนึ่งวิธีสอดคล้องกับเฟรมสแต็ก หากวิธีการหลักเรียกวิธีการอื่นมันจะกดทีละตัวในสแต็ก มีตัวแปรท้องถิ่นประเภท A ในวิธีหลัก ในตอนแรกค่าของ A เป็นโมฆะ ตัวสร้างของคลาส A ถูกเรียกผ่านใหม่ วิธี A () ถูกสร้างขึ้นในสแต็กและวัตถุ A ถูกสร้างขึ้นในกอง จากนั้นที่อยู่วัตถุจะถูกจ่ายให้กับ A ในสแต็ก ในเวลานี้ A มีที่อยู่วัตถุ
3. เมื่อมีการเรียก A.Width ข้อมูลพื้นที่วิธีการจะถูกเรียก
เมื่อคลาสถูกโหลดโดยอ้างอิงคลาสจะโหลดเพียงครั้งเดียว
การอ้างอิงที่ใช้งานอยู่ของคลาส (การเริ่มต้นคลาสจะเกิดขึ้นอย่างแน่นอน)
java.lang.reflect เพื่อโทรกลับไปที่คลาส การอ้างอิงแบบพาสซีฟไปยังคลาส (การเริ่มต้นคลาสจะไม่เกิดขึ้น)
ตัวอย่างที่ 2:
การสาธิตคลาสสาธารณะ 01 {คงที่ {system.out.println ("การเริ่มต้นการเริ่มต้นแบบคงที่ DEMO01"); } โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่นข้อยกเว้น {system.out.println ("วิธีหลักของ Demo01!"); System.out.println (System.getProperty ("java.class.path")); // การอ้างอิงที่ใช้งานอยู่ // ใหม่ a (); // system.out.println (a.width); // class.forname ("com.sinosoft.test.a"); // การอ้างอิงแบบพาสซีฟ // system.out.println (a.max); // a [] as = new a [10]; System.out.println (b.width); // คลาส B จะไม่ถูกโหลด}} คลาส B ขยาย {คงที่ {system.out.println ("การเริ่มต้นแบบคงที่ b"); }} คลาส A ขยาย a_father {ความกว้าง int คงที่สาธารณะ = 100; // ตัวแปรสแตติก, โดเมนคงที่ฟิลด์สาธารณะคงที่สุดท้าย int max = 100; Static {System.out.println ("เริ่มต้นคลาส A"); ความกว้าง = 300; } สาธารณะ a () {system.out.println ("สร้างวัตถุของคลาส A"); }} คลาส a_father ขยายวัตถุ {static {system.out.println ("การเริ่มต้นแบบคงที่ a_father"); -สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะมีค่าอ้างอิงบางอย่างสำหรับการศึกษาหรือที่ทำงานของทุกคน หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร ขอบคุณสำหรับการสนับสนุน Wulin.com