วิธีที่ง่ายที่สุดในการทำความเข้าใจ Java Generics คือการพิจารณาว่าเป็นไวยากรณ์ที่สะดวกซึ่งสามารถช่วยคุณได้บ้างในการคัดเลือกนักแสดงประเภท Java:
รายการ <apple> box = ... ; Apple Apple = box.get (0);
รหัสด้านบนแสดงอย่างชัดเจน: กล่องเป็นรายการที่มีวัตถุ Apple เมธอด Get ส่งคืนอินสแตนซ์ของวัตถุ Apple และกระบวนการนี้ไม่จำเป็นต้องมีการแปลงประเภท ไม่มียาสามัญต้องเขียนรหัสข้างต้นเช่นนี้:
กล่องรายการ = ... ; Apple = (Apple) Box.get (0);
เป็นที่ชัดเจนว่าประโยชน์หลักของยาสามัญคือการอนุญาตให้คอมไพเลอร์เก็บข้อมูลประเภทของพารามิเตอร์ดำเนินการตรวจสอบประเภทและดำเนินการแปลงประเภท: คอมไพเลอร์ทำให้มั่นใจได้ว่าการแปลงประเภทเหล่านี้ถูกต้องอย่างแน่นอน เมื่อเทียบกับการใช้โปรแกรมเมอร์เพื่อจดจำประเภทวัตถุและดำเนินการแปลงประเภท - ซึ่งจะทำให้เกิดความล้มเหลวเมื่อโปรแกรมทำงานซึ่งยากต่อการดีบักและแก้ปัญหา คอมไพเลอร์สามารถช่วยโปรแกรมเมอร์บังคับให้มีการตรวจสอบประเภทจำนวนมากในเวลาคอมไพล์และค้นหาข้อผิดพลาด
องค์ประกอบของยาสามัญ
องค์ประกอบของยาสามัญนำไปสู่แนวคิดของตัวแปรประเภท ตามข้อกำหนดภาษา Java ตัวแปรประเภทเป็นประเภทของ glyph ที่ไม่ จำกัด ซึ่งเกิดขึ้นจากสถานการณ์ต่อไปนี้:
การประกาศคลาสทั่วไปการประกาศอินเทอร์เฟซทั่วไปวิธีการประกาศทั่วไปการประกาศตัวสร้างโครงสร้างทั่วไป
คลาสและอินเทอร์เฟซทั่วไป
หากมีตัวแปรประเภทหนึ่งหรือมากกว่าในคลาสหรืออินเทอร์เฟซมันเป็นทั่วไป ประเภทตัวแปรถูกกำหนดโดยวงเล็บมุมและวางหลังคลาสหรือชื่ออินเตอร์เฟส:
รายการอินเตอร์เฟสสาธารณะ <t> ขยายคอลเลกชัน <t> {... }พูดง่ายๆคือบทบาทของตัวแปรประเภทเป็นเหมือนพารามิเตอร์ซึ่งให้ข้อมูลกับคอมไพเลอร์สำหรับการตรวจสอบประเภท
ชั้นเรียนจำนวนมากในไลบรารีคลาส Java เช่นเฟรมเวิร์กคอลเลกชันทั้งหมดได้รับการแก้ไขในรูปแบบทั่วไป ตัวอย่างเช่นรายการอินเทอร์เฟซที่เราใช้ในรหัสแรกด้านบนเป็นคลาสทั่วไป ในรหัสนั้นกล่องเป็นวัตถุรายการ <apple> ซึ่งเป็นอินสแตนซ์ของการใช้งานคลาสของอินเทอร์เฟซรายการที่มีตัวแปรประเภท Apple คอมไพเลอร์ใช้พารามิเตอร์ตัวแปรประเภทนี้เพื่อแปลงเมธอด Get โดยอัตโนมัติเมื่อมีการเรียกและส่งคืนวัตถุ Apple
ในความเป็นจริงแท็กทั่วไปที่เพิ่งเกิดขึ้นใหม่นี้หรือวิธีการรับในอินเทอร์เฟซรายการนี้มีดังนี้:
t รับ (INT ดัชนี);
วิธีการรับจริงจะส่งคืนวัตถุประเภท T ซึ่งเป็นตัวแปรประเภทในรายการ <t> การประกาศ
วิธีการทั่วไปและตัวสร้าง
คล้ายกันมากถ้ามีการประกาศตัวแปรประเภทหนึ่งขึ้นไปในวิธีการและตัวสร้างพวกเขายังสามารถเป็นทั่วไป
สาธารณะคงที่ <t> t getFirst (รายการ <t> รายการ)
วิธีนี้จะยอมรับพารามิเตอร์รายการ <t> และส่งคืนวัตถุประเภท T คุณสามารถใช้คลาสทั่วไปที่มีให้ในไลบรารีคลาส Java หรือคุณสามารถใช้คลาสทั่วไปของคุณเอง ข้อมูลการเขียนแบบปลอดภัย ... รหัสต่อไปนี้เป็นตัวอย่าง เราสร้างอินสแตนซ์ <string> รายการแล้วโหลดข้อมูลบางส่วน:
รายการ <String> str = arrayList ใหม่ <String> (); str.add ("สวัสดี"); Str.add ("World.");หากเราพยายามโหลดวัตถุอื่นในรายการ <String> คอมไพเลอร์จะแจ้งข้อผิดพลาด:
str.add (1);
ข้อมูลการอ่านประเภทที่ปลอดภัย ...
เมื่อเราใช้วัตถุรายการ <string> มันรับประกันได้เสมอว่าเราจะได้รับวัตถุสตริง:
String mystring = str.get (0);
Traversal: หลายคลาสในไลบรารีคลาสเช่นตัววนซ้ำ <t> มีฟังก์ชั่นที่ได้รับการปรับปรุงและมีการรวมกัน เมธอดตัววนซ้ำ () ในรายการ <t> อินเทอร์เฟซจะส่งคืน ITERATOR <T> วัตถุที่ส่งคืนโดยวิธี t ถัดไป () ไม่จำเป็นต้องแปลงประเภทคุณจะได้รับประเภทที่ถูกต้องโดยตรง
สำหรับ (iterator <string> iter = str.iterator (); iter.hasnext ();) {string s = iter.next (); system.out.print (s);}ด้วย foreach, "สำหรับแต่ละ" ไวยากรณ์ยังได้รับประโยชน์จากยาสามัญ รหัสก่อนหน้านี้สามารถเขียนได้เช่นนี้:
สำหรับ (String s: str) {system.out.print (s);}นี่เป็นเรื่องง่ายที่จะอ่านและบำรุงรักษา
การห่อหุ้มอัตโนมัติ (autoboxing) และการแกะกล่องอัตโนมัติ (autounboxing) เมื่อใช้ Java Generics คุณลักษณะทั้งสองของ Autoboxing/Autounboxing จะถูกนำมาใช้โดยอัตโนมัติเช่นเดียวกับรหัสต่อไปนี้:
รายการ <จำนวนเต็ม> ints = arrayList ใหม่ <integer> (); ints.add (0); ints.add (1); int sum = 0; สำหรับ (int i: ints) {sum += i; -อย่างไรก็ตามสิ่งหนึ่งที่คุณต้องเข้าใจคือบรรจุภัณฑ์และการแกะกล่องจะทำให้เกิดการสูญเสียประสิทธิภาพและทั้งหมดควรใช้ความระมัดระวัง
Generics เป็นคุณสมบัติใหม่ของ Java SE 1.5 Essence of Generics เป็นประเภทพารามิเตอร์นั่นคือประเภทข้อมูลที่ดำเนินการถูกระบุเป็นพารามิเตอร์ ประเภทพารามิเตอร์นี้สามารถใช้ในการสร้างคลาสอินเตอร์เฟสและวิธีการและเรียกว่าคลาสทั่วไปอินเตอร์เฟสทั่วไปและวิธีการทั่วไปตามลำดับ
ข้อได้เปรียบของการแนะนำทั่วไปในภาษา Java คือพวกเขาปลอดภัยและเรียบง่าย
ก่อนที่ Java SE 1.5 โดยไม่มีชื่อว่า "การทำให้เป็นอันตราย" ของพารามิเตอร์สามารถทำได้โดยการอ้างอิงวัตถุประเภท ข้อเสียของ "การทำให้เป็นอันตราย" คือจำเป็นต้องมีการแปลงประเภทการหล่ออย่างชัดเจนและการแปลงนี้จำเป็นต้องมีนักพัฒนาซอฟต์แวร์ในการทำนายประเภทพารามิเตอร์จริง ในกรณีที่มีข้อผิดพลาดในการแปลงประเภทการหล่อคอมไพเลอร์อาจไม่แจ้งข้อผิดพลาดและข้อยกเว้นจะเกิดขึ้นก็ต่อเมื่อทำงานซึ่งเป็นความเสี่ยงด้านความปลอดภัย
ข้อได้เปรียบของยาสามัญคือพวกเขาตรวจสอบประเภทความปลอดภัยเมื่อรวบรวมและ casts ทั้งหมดเป็นไปโดยอัตโนมัติและโดยปริยายปรับปรุงอัตราการใช้รหัสซ้ำ
มีกฎและข้อ จำกัด บางประการในการใช้งานทั่วไป:
1. พารามิเตอร์ประเภทของประเภททั่วไปสามารถเป็นประเภทคลาส (รวมถึงคลาสที่กำหนดเอง) ไม่ใช่ประเภทง่าย ๆ
2. ประเภททั่วไปเดียวกันสามารถสอดคล้องกับหลายเวอร์ชัน (เนื่องจากประเภทพารามิเตอร์ไม่แน่นอน) และอินสแตนซ์ของคลาสทั่วไปของเวอร์ชันที่แตกต่างกันนั้นเข้ากันไม่ได้
3. อาจมีพารามิเตอร์หลายประเภทสำหรับทั่วไป
4. ประเภทพารามิเตอร์ทั่วไปสามารถใช้ขยายคำสั่งเช่น กลายเป็น "ประเภทที่มีขอบเขต" เป็นประจำ
5. ประเภทพารามิเตอร์ของประเภททั่วไปยังสามารถเป็นไวด์การ์ดได้ ตัวอย่างเช่นคลาส classtype = class.forname (java.lang.string);
Generics ยังมีอินเทอร์เฟซวิธีการ ฯลฯ ที่มีเนื้อหาจำนวนมากและต้องใช้ความพยายามในการทำความเข้าใจมาสเตอร์และนำไปใช้อย่างเชี่ยวชาญ ต่อไปนี้เป็นตัวอย่างสองตัวอย่างที่ฉันเขียนเมื่อฉันเรียนรู้เกี่ยวกับทั่วไป (เขียนตามความประทับใจที่ฉันเห็น) ซึ่งสามารถตระหนักถึงฟังก์ชั่นเดียวกัน หนึ่งใช้ยาสามัญและอื่น ๆ ไม่ได้ ผ่านการเปรียบเทียบคุณสามารถเรียนรู้แอปพลิเคชันทั่วไปได้อย่างรวดเร็ว เรียนรู้สิ่งนี้และเรียนรู้โดยทั่วไป 70% ของเนื้อหาของทั่วไป
ตัวอย่างที่ 1: มีการใช้ยาชื่อสามัญ
ชั้นเรียนสาธารณะสุภาพบุรุษ {ส่วนตัว t ob; // กำหนดตัวแปรสมาชิกทั่วไป Gen (t ob) {this.ob = ob; } สาธารณะ t getob () {return ob; } โมฆะสาธารณะ setob (t ob) {this.ob = ob; } โมฆะสาธารณะ showtyep () {system.out.println ("ประเภทจริงของ t คือ:" + ob.getClass (). getName ()); }} คลาสสาธารณะ gendemo {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// กำหนดรุ่นจำนวนเต็มของคลาสทั่วไป Gen Gen Intob = new Geninteger (88); intob.showtyep (); int i = intob.getob (); System.out.println ("value =" + i); System.out.println ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ตัวอย่างที่ 2: ไม่มีการใช้ยาชื่อสามัญ
ชั้นเรียนสาธารณะ Gen2 {วัตถุส่วนตัว OB; // กำหนดประเภทสมาชิกทั่วไป Gen2 (Object ob) {this.ob = ob; } วัตถุสาธารณะ getob () {return ob; } โมฆะสาธารณะ setob (Object ob) {this.ob = ob; } โมฆะสาธารณะ showtyep () {system.out.println ("ประเภทจริงของ t คือ:" + ob.getClass (). getName ()); }} คลาสสาธารณะ gendemo2 {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// กำหนดรุ่นจำนวนเต็มของคลาส gen2 gen2 intob = new gen2 (จำนวนเต็มใหม่ (88)); intob.showtyep (); int i = (จำนวนเต็ม) intob.getob (); i); System.out.println ("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- strob.getob (); system.out.println ("value =" + s);ผลการทำงาน:
ผลลัพธ์ของการรันการสาธิตในตัวอย่างทั้งสองนั้นเหมือนกันและเอาต์พุตคอนโซลมีดังนี้:
ประเภทจริงของ t คือ:
java.lang.integer
ค่า = 88
-
ประเภทที่แท้จริงของ t คือ: java.lang.string
ค่า = สวัสดี Gen!
กระบวนการเสร็จสิ้นด้วยรหัสออก 0
หากคุณเข้าใจสิ่งนี้คุณจะไม่เป็นปัญหาในอนาคตเมื่อแอปพลิเคชันพื้นฐานและการอ่านรหัสพื้นฐาน
ข้างต้นคือการวิเคราะห์ตัวอย่างของ Java Generics เพื่อนที่เรียนรู้ Java Generics สามารถอ้างถึงได้