คำอธิบายโดยละเอียดเกี่ยวกับการสะท้อนชวา
บทความนี้ยังคงใช้ตัวอย่างเล็ก ๆ น้อย ๆ เพื่อแสดงให้เห็นเพราะฉันมักจะรู้สึกว่ากรณีที่ขับเคลื่อนด้วยเป็นสิ่งที่ดีที่สุดมิฉะนั้นถ้าคุณอ่านเฉพาะทฤษฎีคุณจะไม่เข้าใจหลังจากอ่าน อย่างไรก็ตามขอแนะนำให้คุณมองย้อนกลับไปที่ทฤษฎีหลังจากอ่านบทความและมีความเข้าใจที่ดีขึ้น
ข้อความหลักเริ่มต้นด้านล่าง
[กรณีที่ 1] รับแพ็คเกจที่สมบูรณ์และชื่อคลาสผ่านวัตถุ
แพคเกจสะท้อน; /*** รับชื่อแพ็คเกจที่สมบูรณ์และชื่อคลาสผ่านวัตถุ**/คลาสการสาธิตคลาส {// รหัสอื่น ๆ ... } คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {ตัวอย่างสาธิต = การสาธิตใหม่ (); System.out.println (demo.getClass (). getName ()); -【ผลการทำงาน】: rechorm.demo
เพิ่มประโยค: วัตถุทั้งหมดของคลาสเป็นอินสแตนซ์ของคลาส
【กรณีที่ 2 】อินสแตนซ์คลาส
แพ็คเกจสะท้อน; การสาธิตคลาส {// รหัสอื่น ๆ ... } คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {คลาส <?> demo1 = null; คลาส <?> demo2 = null; คลาส <?> demo3 = null; ลอง {// โดยทั่วไปพยายามใช้แบบฟอร์มนี้ demo1 = class.forname ("rechers.demo"); } catch (exception e) {e.printstacktrace (); } demo2 = demo ใหม่ (). getClass (); demo3 = demo.class; System.out.println ("ชื่อคลาส"+demo1.getName ()); System.out.println ("ชื่อคลาส"+demo2.getName ()); System.out.println ("ชื่อคลาส"+demo3.getName ()); -【ผลการดำเนินงาน】:
คลาส namereflect.demo
คลาส namereflect.demo
คลาส namereflect.demo
[กรณีที่ 3] อินสแตนซ์วัตถุของคลาสอื่น ๆ ผ่านชั้นเรียน
วัตถุอินสแตนซ์โดยการสร้างที่ไม่ใช่พารามิเตอร์
แพคเกจสะท้อน; บุคคลในชั้นเรียน {สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; } public int getage () {return Age; } การตั้งค่าโมฆะสาธารณะ (อายุ int) {this.age = อายุ; } @Override สตริงสาธารณะ toString () {return "["+this.name+""+this.age+"]"; } ชื่อสตริงส่วนตัว; อายุ int ส่วนตัว; } คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } บุคคลต่อ = null; ลอง {per = (บุคคล) demo.newinstance (); } catch (InstantiationException e) {// todo บล็อก catch block ที่สร้างอัตโนมัติ E.PrintStackTrace (); } catch (unglemalAccessException e) {// todo catch block catch auto-generated e.printstacktrace (); } per.setName ("rollen"); การตั้งค่า (20); System.out.println (ต่อ); -【ผลการดำเนินงาน】:
[Rollen 20]
แต่โปรดทราบว่าเมื่อเรายกเลิกตัวสร้างพารามิเตอร์เริ่มต้นด้วยตนเองเช่นหลังจากที่เรากำหนดตัวสร้างเพียงหนึ่งตัวที่มีพารามิเตอร์ข้อผิดพลาดจะเกิดขึ้น:
ตัวอย่างเช่นฉันกำหนดตัวสร้าง:
บุคคลสาธารณะ (ชื่อสตริงอายุ int) {this.age = อายุ; this.name = ชื่อ; -จากนั้นเรียกใช้โปรแกรมข้างต้นต่อไปและจะปรากฏขึ้น:
java.lang.instantiationexception: Reflect.person
ที่ java.lang.class.newinstance0 (class.java:340)
ที่ java.lang.class.newinstance (class.java:308)
ที่ Reflect.hello.main (hello.java:39)
ข้อยกเว้นในเธรด "หลัก" java.lang.nullpointerexception
ที่ Reflect.hello.main (hello.java:47)
ดังนั้นเมื่อคุณเขียนวัตถุที่ใช้คลาสเพื่อยกตัวอย่างคลาสอื่น ๆ คุณต้องกำหนดตัวสร้างของคุณเองโดยไม่ต้องพารามิเตอร์
[กรณี] call constructors ในคลาสอื่น ๆ ผ่านคลาส (คุณยังสามารถสร้างวัตถุของคลาสอื่น ๆ ผ่านคลาสด้วยวิธีนี้)
แพคเกจสะท้อน; นำเข้า java.lang.reflect.constructor; บุคคลในชั้นเรียน {บุคคลสาธารณะ () {} บุคคลสาธารณะ (ชื่อสตริง) {this.name = name; } บุคคลสาธารณะ (อายุ int) {this.age = อายุ; } บุคคลสาธารณะ (ชื่อสตริงอายุ int) {this.age = อายุ; this.name = ชื่อ; } สตริงสาธารณะ getName () {ชื่อคืน; } public int getage () {return Age; } @Override สตริงสาธารณะ toString () {return "["+this.name+""+this.age+"]"; } ชื่อสตริงส่วนตัว; Private Int อายุ;} คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } person per1 = null; บุคคล PER2 = NULL; บุคคลต่อ 3 = null; บุคคล PER4 = NULL; // รับตัวสร้างตัวสร้างทั้งหมด <?> cons [] = demo.getConstructors (); ลอง {per1 = (บุคคล) ข้อเสีย [0] .NewInstance (); Per2 = (บุคคล) ข้อเสีย [1] .Newinstance ("Rollen"); per3 = (บุคคล) ข้อเสีย [2] .Newinstance (20); Per4 = (บุคคล) ข้อเสีย [3] .Newinstance ("Rollen", 20); } catch (exception e) {e.printstacktrace (); } system.out.println (per1); System.out.println (Per2); System.out.println (Per3); System.out.println (Per4); -【ผลการดำเนินงาน】:
[null 0]
[Rollen 0]
[NULL 20]
[Rollen 20]
【กรณี】
ส่งคืนอินเทอร์เฟซที่ใช้โดยคลาส:
แพคเกจสะท้อน; อินเตอร์เฟสจีน {สตริงสุดท้ายคงที่สาธารณะชื่อ = "โรลเลน"; สาธารณะคงที่สาธารณะอายุ = 20; โมฆะสาธารณะ Sayschina (); โมฆะสาธารณะ Sayshello (ชื่อสตริงอายุ int);} คนในชั้นเรียนใช้จีน {บุคคลสาธารณะ () {} บุคคลสาธารณะ (เพศสตริง) {this.sex = เพศ; } Public String getSex () {return sex; } โมฆะสาธารณะ setsex (String sex) {this.sex = sex; } @Override โมฆะสาธารณะ saychina () {system.out.println ("สวัสดีจีน"); } @Override โมฆะสาธารณะ Sayshello (ชื่อสตริงอายุ int) {system.out.println (ชื่อ+""+อายุ); } String Private String Sex;} คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (String [] args) {class <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } // บันทึกคลาสอินเตอร์เฟสทั้งหมด <?> intes [] = demo.getInterfaces (); สำหรับ (int i = 0; i <intes.length; i ++) {system.out.println ("อินเตอร์เฟสที่ใช้งาน"+intes [i] .getName ()); -【ผลการดำเนินงาน】:
อินเทอร์เฟซที่ใช้งานสะท้อนให้เห็น
(โปรดทราบว่าตัวอย่างต่อไปนี้จะใช้คลาสบุคคลของตัวอย่างนี้ดังนั้นเพื่อประหยัดพื้นที่เราจะไม่วางส่วนรหัสบุคคลที่นี่อีกต่อไปเฉพาะรหัสของคลาสหลักสวัสดี)
【กรณี】: รับคลาสแม่ในชั้นเรียนอื่น ๆ
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } // รับคลาสพาเรนต์คลาส <?> temp = demo.getSuperClass (); System.out.println ("คลาสแม่ที่สืบทอดมาคือ:"+temp.getName ()); -【การรันผลลัพธ์】
คลาสแม่ที่สืบทอดมาคือ: java.lang.Object
【กรณี】: รับตัวสร้างทั้งหมดในชั้นเรียนอื่น ๆ
ตัวอย่างนี้ต้องเพิ่ม import java.lang.reflect.* ที่จุดเริ่มต้นของโปรแกรม;
จากนั้นเขียนคลาสหลักเป็น:
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } constructor <?> cons [] = demo.getConstructors (); สำหรับ (int i = 0; i <coms.length; i ++) {system.out.println ("constructor:"+cons [i]); -【ผลการดำเนินงาน】:
วิธีการสร้าง: public retrict.person ()
Constructor: Public Reflect.person (java.lang.string)
แต่ผู้อ่านอย่างระมัดระวังจะพบว่าตัวสร้างข้างต้นไม่มีตัวดัดแปลงเช่นสาธารณะหรือส่วนตัว
มารับตัวดัดแปลงในตัวอย่างต่อไปนี้
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } constructor <?> cons [] = demo.getConstructors (); สำหรับ (int i = 0; i <coms.length; i ++) {คลาส <?> p [] = cons [i] .getParameterTypes (); System.out.print ("ตัวสร้าง:"); int mo = cons [i] .getModifiers (); System.out.print (modifier.toString (mo)+""); System.out.print (ข้อเสีย [i] .getName ()); System.out.print ("("); สำหรับ (int j = 0; j <p.length; ++ j) {system.out.print (p [j] .getName ()+"arg"+i); ถ้า (j <p.length-1) {system.out.print (","); -【ผลการดำเนินงาน】:
Constructor: Public Reflect.person () {}
Constructor: Public Reflect.person (java.lang.string arg1) {}
บางครั้งอาจมีข้อยกเว้นในวิธีการฮ่าฮ่า มาดูกันเถอะ:
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } วิธีการ [] = demo.getMethods (); สำหรับ (int i = 0; i <method.length; ++ i) {class <?> returnType = method [i] .getReturntype (); คลาส <?> para [] = วิธี [i] .getParameterTypes (); int temp = วิธีการ [i] .getModifiers (); System.out.print (modifier.toString (temp)+""); System.out.print (returntype.getName ()+""); System.out.print (วิธีการ [i] .getName ()+""); System.out.print ("("); สำหรับ (int j = 0; j <para.length; ++ j) {system.out.print (para [j] .getName ()+""+"arg"+j) ถ้า (j <para.length-1) {system.out.print (","); if (exce.length> 0) {system.out.print (") พ่น"); สำหรับ (int k = 0; k <exce.length; ++ k) {system.out.print (exce [k] .getName ()+""); if (k <exce.length-1) {system.out.print (","); }}} else {system.out.print (")"); } system.out.println (); -【ผลการดำเนินงาน】:
สาธารณะ java.lang.string getsex ()
โมฆะสาธารณะ setsex (java.lang.string arg0)
โมฆะสาธารณะ Sayschina ()
โมฆะสาธารณะ Sayshello (java.lang.string arg0, int arg1)
Public Final Native Void Wait (Long Arg0) โยน java.lang.interruphedException
โมฆะสุดท้ายสาธารณะรอ () โยน java.lang.interruptedException
Public Final Void Wait (Long Arg0, int arg1) โยน java.lang.interruptedException
บูลีนสาธารณะเท่ากับ (java.lang.Object arg0)
สาธารณะ java.lang.string toString ()
hashcode int สาธารณะพื้นเมือง ()
Java.lang.lang.Class GetClass ()
โมฆะพื้นเมืองสุดท้ายสาธารณะแจ้งเตือน ()
เป็นโมฆะพื้นเมืองสุดท้ายสาธารณะ Notifyall ()
[กรณี] ถัดไปขอให้ได้คุณสมบัติทั้งหมดของชั้นเรียนอื่น ๆ ในที่สุดฉันจะแยกพวกเขาออกมาด้วยกันนั่นคือเพื่อให้ได้กรอบทั้งหมดของชั้นเรียนผ่านชั้นเรียน
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); - System.out.println ("============================================================================================================= - - - Permission Modifier int mo = field [i] .getModifiers (); System.out.println ("============================================================================================================== - - - Filed1 = demo.getfields (); สำหรับ (int j = 0; j <filed1.length; j ++) {// modifier การอนุญาต int mo = filed1 [j] .getModifiers (); String priv = modifier.toString (MO); // คลาสประเภทคุณสมบัติ <?> type = filed1 [j] .getType (); System.out.println (priv + "" + type.getName () + "" + filed1 [j] .getName () + ";"); -【ผลการดำเนินงาน】:
-
Java.lang.String Sex;
-
สาธารณะคงที่สุดท้าย Java.lang.string ชื่อ;
อายุ int สุดท้ายคงที่
[กรณี] ในความเป็นจริงวิธีการในชั้นเรียนอื่น ๆ สามารถเรียกผ่านการสะท้อน:
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } ลอง {// การเรียกเมธอด saychina ในวิธีการคลาสบุคคล = demo.getMethod ("Saychina"); method.invoke (demo.newinstance ()); // เรียกวิธี Sayhello ของบุคคล = demo.getMethod ("sayhello", string.class, int.class); Method.invoke (Demo.Newinstance (), "Rollen", 20); } catch (exception e) {e.printstacktrace (); -【ผลการดำเนินงาน】:
สวัสดีจีน
โรลเลน 20
case case 】ชุดโทรและรับวิธีการเรียนอื่น ๆ
คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คลาส <?> demo = null; วัตถุ obj = null; ลอง {demo = class.forName ("revel.person"); } catch (exception e) {e.printstacktrace (); } ลอง {obj = demo.newinstance (); } catch (exception e) {e.printstacktrace (); } setter (obj, "sex", "male", string.class); getter (obj, "เพศ"); } / ** * @param obj * วัตถุของการดำเนินการ * @param att * แอตทริบิวต์ของการดำเนินการ * * / โมฆะคงที่สาธารณะ getter (Object obj, String att) {ลอง {วิธีการ = obj.getClass (). getMethod ("รับ" + att); System.out.println (method.invoke (obj)); } catch (exception e) {e.printstacktrace (); }} / ** * @param obj * วัตถุของการดำเนินการ * @param att * แอตทริบิวต์ของการดำเนินการ * @param ค่า * ตั้งค่า * @param ประเภท * แอตทริบิวต์ของพารามิเตอร์ * * / โมฆะคงที่สาธารณะ method.invoke (obj, ค่า); } catch (exception e) {e.printstacktrace (); }}} // คลาสสิ้นสุด【ผลการดำเนินงาน】:
ชาย
【กรณี】การดำเนินการโดยการสะท้อนกลับ
คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] args) โยนข้อยกเว้น {คลาส <?> demo = null; วัตถุ obj = null; DEMO = class.forName ("revel.person"); obj = demo.newinstance (); ฟิลด์ฟิลด์ = demo.getDeclaredField ("เพศ"); field.setAccessible (จริง); Field.set (obj, "Male"); System.out.println (field.get (obj)); }} // คลาสสิ้นสุด[กรณี] รับและแก้ไขข้อมูลของอาร์เรย์ผ่านการสะท้อน:
นำเข้า java.lang.reflect.*; คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {int [] temp = {1,2,3,4,4,5}; คลาส <?> demo = temp.getClass (). getComponentYpe (); System.out.println ("ประเภทอาร์เรย์:"+demo.getName ()); System.out.println ("ความยาวอาร์เรย์"+array.getLength (temp)); System.out.println ("องค์ประกอบแรกของอาร์เรย์:"+array.get (temp, 0)); array.set (อุณหภูมิ, 0, 100); System.out.println ("หลังจากแก้ไของค์ประกอบแรกของอาร์เรย์คือ:"+array.get (temp, 0)); -【ผลการดำเนินงาน】:
ประเภทอาร์เรย์: int
ความยาวอาร์เรย์ 5
องค์ประกอบแรกของอาร์เรย์: 1
หลังจากการแก้ไของค์ประกอบแรกของอาร์เรย์คือ: 100
【เคส】ปรับเปลี่ยนขนาดอาร์เรย์ผ่านการสะท้อนกลับ
คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {int [] temp = {1,2,3,4,5,6,7,7,8,9}; int [] newTemp = (int []) arrayinc (อุณหภูมิ, 15); พิมพ์ (Newtemp); System.out.println ("================================================================================== - String []) ArrayInc (ATR, 8); System.ArrayCopy (OBJ, 0, NewAr, 0, CO); array.getLength (obj);【ผลการดำเนินงาน】:
ความยาวอาร์เรย์คือ: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 ===============================================
ความยาวอาร์เรย์คือ: 8
ABC NULL NULL NULL NULL NULL
ตัวแทนไดนามิก
[กรณี] ก่อนอื่นมาดูวิธีรับตัวโหลดคลาส:
การทดสอบคลาส {} คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {ทดสอบ t = การทดสอบใหม่ (); System.out.println ("classloader"+t.getClass (). getClassLoader (). getClass (). getName ()); -【เอาต์พุตโปรแกรม】:
คลาสโหลดเดอร์ sun.misc.launcher $ appclassloader
ในความเป็นจริงมีรถตักคลาสสามประเภทใน Java
1) Bootstrap classloader ตัวโหลดนี้เขียนใน C ++ และไม่ค่อยเห็นในการพัฒนาทั่วไป
2) Extension classloader ใช้ในการโหลดคลาสเพิ่มเติมโดยทั่วไปจะสอดคล้องกับคลาสในไดเรกทอรี JRE/LIB/EXT
3) AppClassLoader โหลดคลาสที่ระบุโดย ClassPath และเป็นตัวโหลดที่ใช้กันมากที่สุด นอกจากนี้ยังเป็นตัวโหลดเริ่มต้นใน Java
หากคุณต้องการทำพร็อกซีแบบไดนามิกให้เสร็จสมบูรณ์ก่อนอื่นคุณต้องกำหนดคลาสย่อยของอินเทอร์เฟซ InvocationHandler และการดำเนินการเฉพาะของพร็อกซีเสร็จสมบูรณ์
แพ็คเกจสะท้อนกลับนำเข้า java.lang.reflect.*; // กำหนดหัวเรื่องอินเทอร์เฟซของโครงการ {สตริงสาธารณะบอกว่า (ชื่อสตริงอายุ int);} // กำหนดคลาสโปรเจ็กต์จริง RealSubject นำมาใช้ {@Override Public String บอกว่า (ชื่อสตริงอายุ int) {ชื่อคืน + "" อายุ; }} คลาส MyInVocationHandler ใช้งาน InvocationHandler {วัตถุส่วนตัว obj = null; วัตถุสาธารณะผูก (Object obj) {this.obj = obj; ส่งคืน proxy.newproxyinstance (obj.getclass (). getclassloader (), obj .getClass (). getInterfaces (), สิ่งนี้); } @Override วัตถุสาธารณะเรียกใช้ (พร็อกซีวัตถุ, วิธีการ, วัตถุ [] args) พ่น throwable {วัตถุอุณหภูมิ = method.invoke (this.obj, args); กลับอุณหภูมิ; }} คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {myinvocationhandhand demo = new MyinVocationHandler (); subs sub = (หัวเรื่อง) demo.bind (ใหม่ realsubject ()); String info = sub.say ("Rollen", 20); System.out.println (ข้อมูล); -【ผลการดำเนินงาน】:
โรลเลน 20
วงจรชีวิตของชั้นเรียน
หลังจากรวบรวมคลาสแล้วขั้นตอนต่อไปคือเริ่มใช้คลาส หากคุณต้องการใช้คลาสมันแยกออกจาก JVM ได้อย่างแน่นอน ในระหว่างการดำเนินการโปรแกรม JVM จะเสร็จสมบูรณ์ผ่านสามขั้นตอนเหล่านี้: การโหลดการเชื่อมโยงและการเริ่มต้น
การโหลดคลาสจะทำผ่านตัวโหลดคลาส ตัวโหลดโหลดไฟล์ไบนารีของไฟล์. class ลงในพื้นที่เมธอด JVM และสร้างวัตถุ Java.lang.class ที่อธิบายคลาสนี้ในพื้นที่ฮีป ใช้เพื่อห่อหุ้มข้อมูล แต่คลาสเดียวกันจะถูกโหลดโดยตัวโหลดคลาสก่อนหน้านี้
ลิงก์คือการรวบรวมข้อมูลไบนารีเข้ากับสถานะที่สามารถรันได้
ลิงค์แบ่งออกเป็นสามขั้นตอน: การตรวจสอบการเตรียมการและการแยกวิเคราะห์
โดยทั่วไปแล้วการตรวจสอบจะใช้เพื่อยืนยันว่าไฟล์ไบนารีนี้เหมาะสำหรับ JVM ปัจจุบัน (เวอร์ชัน) หรือไม่
การเตรียมการคือการจัดสรรพื้นที่หน่วยความจำสำหรับสมาชิกคงที่ และตั้งค่าเริ่มต้น
การแยกวิเคราะห์หมายถึงกระบวนการแปลงรหัสในพูลคงที่เป็นการอ้างอิงโดยตรงจนกว่าการอ้างอิงเชิงสัญลักษณ์ทั้งหมดจะสามารถใช้งานได้โดยโปรแกรมการทำงาน (สร้างการติดต่อที่สมบูรณ์)
หลังจากเสร็จสิ้นประเภทจะเริ่มต้น หลังจากเริ่มต้นวัตถุของคลาสสามารถใช้ตามปกติ หลังจากที่วัตถุไม่ได้ใช้อีกต่อไปมันจะถูกเก็บรวบรวมขยะ พื้นที่ว่าง
เมื่อไม่มีจุดอ้างอิงไปยังวัตถุคลาสมันจะถูกถอนการติดตั้งสิ้นสุดวงจรชีวิตของชั้นเรียน
ใช้การสะท้อนกลับสำหรับโหมดโรงงาน
มาดูโหมดโรงงานถ้าคุณไม่ต้องการการไตร่ตรอง:
http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144851.html
/ *** @author Rollen-Holt โรงงานของรูปแบบการออกแบบ*/ อินเตอร์เฟสผลไม้ {โมฆะนามธรรมสาธารณะ Eat ();} คลาส Apple ใช้ผลไม้ {โมฆะสาธารณะกิน () {System.out.println ("Apple"); }} คลาสสีส้มใช้ผลไม้ {โมฆะสาธารณะกิน () {system.out.println ("สีส้ม"); }} // สร้างคลาสโรงงาน // กล่าวอีกนัยหนึ่งถ้าเราต้องการแก้ไขคลาสโรงงานเมื่อเพิ่มอินสแตนซ์อื่น ๆ ในโรงงานชั้นเรียนในอนาคต if ("Apple" .Equals (FruitName)) {f = new Apple (); } if ("Orange" .equals (FruitName)) {f = New Orange (); } return f; }} คลาสสวัสดี {โมฆะสาธารณะคงที่หลัก (สตริง [] a) {ผล f = factory.getInstance ("Orange"); f.eat (); -ด้วยวิธีนี้เมื่อเราเพิ่มคลาสย่อยเราต้องปรับเปลี่ยนคลาสโรงงาน หากเราเพิ่มคลาสย่อยมากเกินไปเราจะเปลี่ยนมาก
ทีนี้มาดูกลไกการสะท้อนที่ใช้:
แพคเกจสะท้อน; อินเตอร์เฟสผลไม้ {โมฆะนามธรรมสาธารณะ Eat ();} คลาส Apple ใช้ผลไม้ {โมฆะสาธารณะ Eat () {System.out.println ("Apple"); }} คลาสสีส้มใช้ผลไม้ {โมฆะสาธารณะกิน () {system.out.println ("สีส้ม"); }} โรงงานคลาส {ผลไม้คงที่ getInstance (String className) {Fruit F = NULL; ลอง {f = (ผลไม้) class.forName (className) .newInstance (); } catch (exception e) {e.printstacktrace (); } return f; }} คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] a) {ผล f = factory.getInstance ("revel.apple"); if (f! = null) {f.eat (); -ตอนนี้แม้ว่าเราจะเพิ่มคลาสย่อยได้มากขึ้นคลาสโรงงานไม่จำเป็นต้องแก้ไข
แม้ว่าความรักข้างต้นจะได้รับอินสแตนซ์ของอินเทอร์เฟซผ่านการสะท้อนกลับ แต่ก็ต้องส่งผ่านในแพ็คเกจที่สมบูรณ์และชื่อคลาส ยิ่งไปกว่านั้นผู้ใช้ไม่สามารถรู้ได้ว่ามีคลาสย่อยจำนวนเท่าใดในอินเทอร์เฟซดังนั้นเราจึงกำหนดค่าคลาสย่อยที่ต้องการในรูปแบบของไฟล์แอตทริบิวต์
ลองมาดู: โหมดโรงงานรวมไฟล์แอตทริบิวต์
ก่อนอื่นสร้างไฟล์ทรัพยากรผลไม้ properties
เนื้อหาคือ:
Apple = Reflect.apple
สีส้ม = rechorm.orange
จากนั้นเขียนรหัสคลาสหลัก:
แพคเกจสะท้อน; นำเข้า Java.io.*; นำเข้า Java.util.*; อินเตอร์เฟสผลไม้ {โมฆะนามธรรมสาธารณะ Eat ();} คลาส Apple ใช้ผลไม้ {โมฆะสาธารณะ Eat () {System.out.println ("Apple"); }} คลาสสีส้มใช้ผลไม้ {โมฆะสาธารณะกิน () {system.out.println ("สีส้ม"); }} // การดำเนินการคลาสไฟล์คุณสมบัติ init {คุณสมบัติคงที่สาธารณะ getPro () พ่น filenotFoundException, iOException {Properties Pro = คุณสมบัติใหม่ (); ไฟล์ f = ไฟล์ใหม่ ("fruit.properties"); if (f.exists ()) {pro.load (ใหม่ FileInputStream (f)); } else {pro.setProperty ("Apple", "Reflect.apple"); Pro.SetProperty ("Orange", "Reflect.orange"); Pro.Store (ใหม่ fileOutputStream (F), "คลาสผลไม้"); } return pro; }} โรงงานคลาส {ผลไม้คงที่ getInstance (String className) {Fruit F = NULL; ลอง {f = (ผลไม้) class.forName (className) .newInstance (); } catch (exception e) {e.printstacktrace (); } return f; }} คลาสสวัสดี {โมฆะคงที่สาธารณะหลัก (สตริง [] a) พ่น filenotfoundexception, ioexception {properties pro = init.getPro (); Fruit F = Factory.getInstance (Pro.GetProperty ("Apple")); if (f! = null) {f.eat (); -【รันผลลัพธ์】: แอปเปิ้ล
ข้างต้นเป็นคำอธิบายโดยละเอียดของกลไกการสะท้อนชวา เราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!