จาวาเจเนริค (Java Generics) เป็นความสามารถของภาษาจาวาที่ทำให้ออบเจกต์ที่เราสร้างขึ้นมาสามารถรองรับชนิดของข้อมูลที่เป็นออบเจกต์ที่หลากหลาย การใช้งานจาวาเจเนริคทำได้โดยการสร้างคลาสที่เป็นจาวาเจเนริคขึ้นมานั่นเอง
เพื่อให้เข้าใจจาวาเจเนริคคืออะไรเราจะเปรียบเทียบโดยดูจากการใช้งานอาเรย์(array) และคลาส ArrayList ดังตัวอย่างด้านล่าง
ทั้งอาเรย์และคลาส ArrayList ทำหน้าที่ในการเก็บชุดของข้อมูลเหมือนกัน แต่จากบรรทัดที่ 27 และ 28 เราสร้างอาเรย์เพื่อเก็บชนิดของข้อมูลที่เป็น int และกำหนดค่าให้กับอาเรย์ในบรรทัดที่ 29 และ 30 แต่ในบรรทัดที่ 30 มีการแสดงข้อผิดพลาดเนื่องจากเราพยายามกำหนดค่าที่ชนิดของข้อมูลเป็น String
จากตัวอย่างเดียวกันในบรรทัดที่ 32 เราสร้างออบเจกต์จากคลาส ArrayList และกำหนดค่าให้กับออบเจกต์อาเรย์ลิสต์ในบรรทัดที่ 33 และ 34 ด้วยชนิดของข้อมูลที่เป็น int และ String ตามลำดับจะเห็นว่าไม่มีการแสดงข้อผิดพลาด แสดงว่าออบเจกต์จากคลาส ArrayList รองรับข้อมูลทั้ง 2 แบบ ทั้งนี้เป็นเพราะคลาส ArrayList ถูกออกแบบมาให้รองรับจาวาเจเนริค ต่างจากอาเรย์ที่รองรับเฉพาะข้อมูลตามที่เรากำหนดได้แบบเดียวเท่านั้น
ข้อแตกต่างที่สังเกตุได้จากตัวอย่างคือในการสร้างออบเจกต์จากคลาส Array เราต้องระบุชนิดของข้อมูลที่จะเก็บในอาเรย์ แต่ในการสร้างออบเจกต์จากคลาส ArrayList เราไม่ได้ระบุชนิดของข้อมูล เพราะคลาส ArrayList เป็นจาวาเจเนริค
การใช้งานจาวาเจเนริคแบบไม่ระบุชนิดของออบเจกต์เรียกว่าการใช้งานแบบ raw generics ซึ่งจะมีความเสี่ยงที่จะเกิดข้อผิดพลาดในขั้นตอนการใช้งาน (run-time error) เนื่องจากโปรแกรมของเราคงจะไม่สามารถดำเนินการได้อย่างถูกต้องกับออบเจกต์ทุกชนิดในโลกนี้ เช่น เราอาจจะสร้างคลาสเพื่อรับข้อมูลที่เป็นตัวเลขเพื่อนำไปคำนวณ แต่ถ้ามีการส่งข้อมูลเข้ามาเป็นข้อความ โปรแกรมของเราก็จะทำงานได้ไม่ถูกต้องหรือเกิดข้อผิดพลาดขึ้นมา
ตัวอย่างด้านล่างในบรรทัดที่ 8 เป็นการใช้งานในแบบ raw generics โดยที่ไม่มีการระบุชนิดของออบเจกต์ที่ต้องการ ซึ่งในบรรทัดที่ 20 โปรแกรมของเราจะนำข้อมูลมาคำนวณทางคณิตศาสตร์ แต่เรากำหนดค่าในบรรทัดที่ 12 เป็นข้อความ ซึ่งเราจะไม่พบข้อผิดพลาดอะไรในบรรทัดที่ 12 เนื่องจากคลาส ArrayList เป็นจาวาเจเนริค แต่เมื่อเราสั่งรันโปรแกรมจะพบข้อผิดพลาด
ดังนั้นในภาษาจาวาจึงเพิ่มความสามารถในการกำหนดชนิดของออบเจกต์ขึ้นมาเพื่อช่วยลดข้อผิดพลาดในการเขียนโปรแกรม โดยเราสามารถระบุชนิดของออบเจกต์ที่ต้องการได้ตามรูปแบบดังนี้
ชื่อคลาส<ชนิดของออบเจกต์> ชื่อตัวแปร = new ชื่อคลาส<>()
เราเรียกความสามารถแบบนี้ว่าพารามิเตอร์ไรส์ (parameterize) จากตัวอย่างด้านล่างเป็นการสร้างออบเจกต์จากคลาส ArrayList โดยระบุชนิด
ของออบเจกต์เป็น String
แต่เพื่อให้รองรับกับโปรแกรมที่ถูกพัฒนาจากภาษาจาวาเวอร์ชั่นเก่า ภาษาจาวาจึงไม่ได้บังคับการกำหนดชนิดของออบเจกต์ แต่หากมีการกำหนดชนิดของออบเจกต์ ภาษาจาวาจะช่วยตรวจสอบความถูกต้องในส่วนต่างๆของโปรแกรมให้และแสดงข้อผิดพลาดที่ตรวจพบผ่านทางแอพพลิเคชั่น IDE ที่เราใช้งาน
เราสามารถสร้างคลาสที่เป็นจาวาเจเนริคได้เองโดยการกำหนดพารามิเตอร์ให้กับคลาส โดยมีรูปแบบดังนี้
คีย์เวิร์ดควบคุมการเข้าถึง class ชื่อคลาส <พารามิเตอร์>
การกำหนดพารามิเตอร์สำหรับจาวาเจเนริคมักจะกำหนดเป็นตัวอักษรใหญ่ตัวเดียว ตัวอย่างเช่น
เราสามารถกำหนดชนิดของออบเจกต์ที่จะใช้งานได้ด้วยการระบุคีย์เวิร์ด extends ตามด้วยชื่อคลาสที่ต้องการ เรียกว่า bounded type parameter ดังตัวอย่างด้านล่างเรากำหนดตัวแปรพารามิเตอร์ T ในเครื่องหมาย <> และเรากำหนดว่าชนิดของออบเจกต์จะต้องมาจากคลาส Employee และคลาสลูกของคลาส Employee เท่านั้น
เราสามารถกำหนด bounded type parameter ได้มากกว่าหนึ่งเช่นเดียว
กับการใช้คุณสมบัติการสืบทอด โดยเราสามารถ extends ได้เพียงคลาสเดียวจากนั้นต้องเป็นคลาสแบบอินเตอร์เฟส ดังตัวอย่างด้านล่าง
คีย์เวิร์ดควบคุมการเข้าถึง class ชื่อคลาส <พารามิเตอร์ extends ชื่อคลาส & ชื่อคลาสแบบอินเตอร์เฟส & ชื่อคลาสแบบอินเตอร์เฟส & ชื่อคลาสแบบอินเตอร์เฟส>
ตัวอย่างเช่น
public class ClassName <T extends ClassParameter & Interface1 & Interface2 & Interface3 & Interface4>
ตัวอย่างการสร้างคลาสที่เป็นจาวาเจเนริค เริ่มจากสร้างคลาส Employee โดยมีวัตถุประสงค์เพื่อกำหนดว่าเราจะสร้างกลุ่มของพนักงาน คลาส Employee จึงเก็บเฉพาะชื่อของพนักงาน
จากนั้นเราสร้างคลาสที่สืบทอดมาจากคลาส Employee คือคลาส Accountant และคลาส Engineer เพื่อแยกแยะตำแหน่งงานของพนักงานแต่ละคน เช่น นักบัญชี วิศวกร เป็นต้น
จากนั้นเราสร้างคลาส Department เพื่อเป็นแผนกของพนักงาน เราสร้างให้คลาส Department เป็นคลาสแบบเจเนริคโดยกำหนดพารามิเตอร์เพื่อรองรับการบอกชนิดของออบเจกต์ในประโยคคำสั่งสร้างคลาส และใช้พารามิเตอร์ดังกล่าวแทนชนิดของข้อมูลในประโยคคำสั่งสร้างอาเรย์ลิสต์ และในพารามิเตอร์ของเมธอดด้วย เราสามารถทำความเข้าใจแบบง่ายๆได้ว่าชนิดของออบเจกต์ที่เรากำหนดจะถูกแทนที่ในทุกๆที่ที่เป็นพารามิเตอร์ นั่นหมายถึงคลาสแบบจาวาเจเนริคที่เราสร้างขึ้นมาจะถูกนำไปใช้งานกับออบเจกต์ใดๆก็ได้ตามที่เรากำหนด
จากตัวอย่างด้านล่าง ในการใช้งานเราสร้างออบเจกต์ของพนักงานแต่ละคนขึ้นมา และในบรรทัดที่ 11 และ 12 เราสร้างออบเจกต์ของ Department โดยกำหนดชนิดของออบเจกต์จะใช้เป็น Accountant และ Engineer ตามลำดับซึ่งส่วนนี้คือการใช้งานจาวาเจเนริคและการควบคุมชนิดของออบเจกต์ จากนั้นจึงเรียกใช้เมธอด addmermbers() เพื่อเพิ่มพนักงานลงในแต่ละแผนก สังเกตุว่าหากเราเพิ่มพนักงานที่เป็นคลาสที่ไม่ตรงตามที่กำหนด IntelliJ IDEA จะแสดงข้อผิดพลาดให้ทราบ สรุปว่าคลาส Department ของเราเป็นจาวาเจเนริคและรองรับออบเจกต์ได้หลายแบบแต่เราควบคุมไว้แค่กลุ่มของคลาสลูกของคลาส Employee เท่านั้น
ประโยชน์ของจาวาเจเนริคคือเราสามารถสร้างคลาสหนเดียวแต่สามารถใช้งานกับออบเจกต์ได้หลากหลาย จากตัวอย่างด้านบน หากเราเพิ่มเมธอดที่เกี่ยวกับการคำนวณค่าแรงในคลาส Department ดังนั้นไม่ว่าเราจะสร้างออบเจกต์ Department สำหรับพนักงานกลุ่มไหนก็จะสามารถใช้เมธอดเดียวกันในการคำนวณค่าแรง หากเปรียบเทียบกับการไม่ใช้จาวาเจเนริค เราจะต้องสร้างคลาสตามจำนวนตำแหน่งของพนักงานและในแต่ละคลาสก็จะมีเมธอดที่เหมือนๆกัน ซึ่งก็คือการทำซ้ำโปรแกรมเดิมหลายๆครั้ง ทำให้เป็นการเสียเวลาและหากต้องมีการแก้ไขในภายหลังอาจจะแก้ไขไม่ครบทุกคลาสก็เป็นไปได้