ภาษาจาวาคือภาษาโปรแกรมที่ถูกออกแบบและสร้างโดยบริษัทซัน (Sun) ต่อมาบริษัทออราเคิล (Oracle) ได้เข้าซื้อบริษัทซันและพัฒนาภาษาจาวาต่อเนื่องเรื่อยมา ภาษาจาวาเป็นภาษาที่รองรับการเขียนโปรแกรมเชิงวัตถุ (Object Oriented Programming – OOP)
ข้อดีของภาษาจาวาคือเราสามารถพัฒนาโปรแกรมเพียงครั้งเดียวแต่สามารถนำไปใช้งานกับเครื่องคอมพิวเตอร์ที่ใช้ระบบปฏิบัติการหรือใช้สถาปัตยกรรมตัวประมวลผลที่แตกต่างกันได้ โดยไม่ต้องแก้ไขโปรแกรมหรือคอมไพล์โปรแกรมใหม่
ตัวอย่างระบบปฎิบัติการที่แตกต่างกัน เช่น ระบบปฎิบัติการวินโดส์ (Windows) ระบบปฎิบัติการไอโอเอส (iOS) ระบบปฎิบัติการลินุกซ์ (Linux) ระบบปฏิบัติการ z/OS สำหรับเมนเฟรมของ IBM เป็นต้น
ตัวอย่างสถาปัตยกรรมของหน่วยประมวลผลที่แตกต่างกัน เช่น หน่วยประมวลผลของอินเทล (Intel) ใช้สถาปัตยกรรมแบบ CISC หน่วยประมวลผลของไอบีเอ็ม (IBM) ใช้สถาปัตยกรรมแบบ RISC เป็นต้น
การที่ภาษาจาวาสามารถใช้งานได้กับทุกเครื่องคอมพิวเตอร์มาจากแนวคิดการใช้โปรแกรมจำลองเครื่องคอมพิวเตอร์ขึ้นมาในเครื่องคอมพิวเตอร์จริง และเรียกใช้งานโปรแกรมที่เราพัฒนาขึ้นมาในเครื่องคอมพิวเตอร์จำลองอีกทีหนึ่ง โดยที่โปรแกรมของเราจะเข้าใจว่าตัวเองมันทำงานอยู่บนเครื่องคอมพิวเตอร์จริง แนวคิดนี้เรียกว่าการสร้างเครื่องจักรเสมือน ( virtual machine) โดยไฟล์รหัสต้นฉบับในภาษาจาวา (source code file) จะถูกคอมไพล์ไปเป็นไฟล์ไบนารี่ที่เรียกว่าจาวาไบต์โค๊ด (java byte code file) ซึ่งจะทำงานได้เฉพาะบนเครื่องจักรเสมือนของจาวา (java virtual machine) เท่านั้น
ดังนั้นเมื่อเราต้องการนำโปรแกรมที่เราพัฒนาขึ้นมาไปใช้ที่เครื่องคอมพิวเตอร์เครื่องใดก็เพียงแต่ติดตั้งโปรแกรม java virtual machine ลงไปที่เครื่องคอมพิวเตอร์เครื่องนั้นก็จะสามารถใช้งานโปรแกรมของเราได้โดยที่เราไม่ต้องคอมไพล์โปรแกรมใหม่หรือแก้ไขโปรแกรม
ถ้าเรามองภาพรวมของสิ่งที่เราต้องใช้ตั้งแต่การพัฒนาโปรแกรมไปจนถึงการใช้งานโปรแกรมที่เราเขียนขึ้นมา เราจะต้องมีโปรแกรม JDK (Java Development Kit), โปรแกรม JRE (Java Runtime Environment) และโปรแกรม JVM (Java Virtual Machine) ซึ่งรายละเอียดของแต่ละโปรแกรมจะกล่าวถึงในหัวข้อต่อๆไป
ภาษาจาวาเป็นภาษาที่ใช้การแปลภาษาทั้งแบบคอมไพเลอร์และแบบอิน
เตอร์พรีเตอร์ โดยในขั้นการตอนการแปรภาษาแบบคอมไพล์จะเป็นการแปลจากไฟล์รหัสต้นฉบับไปเป็นไฟล์ไบนารี่ในรูปแบบจาวาไบต์โค๊ด และไฟล์จาวาไบต์โค๊ดจะถูกแปลไปเป็นภาษาที่เครื่องคอมพิวเตอร์เข้าใจด้วย java virtual machine โดยใช้การแปลภาษาแบบอินเตอร์พรีเตอร์อีกทีหนึ่ง
โปรแกรม JDK
JDK ย่อมาจาก Java Development Kit เป็นชุดของโปรแกรมที่ใช้ในการพัฒนาโปรแกรมด้วยภาษาจาวา การพัฒนาโปรแกรมด้วยภาษาจาวาจะถูกแบ่งออกเป็น 3 แบบคือการพัฒนาโปรแกรมสำหรับเครื่องคอมพิวเตอร์เดสก์ทอป (Java SE) การพัฒนาโปรแกรมสำหรับระบบงานขนาดใหญ่ที่ใช้งานบนเครื่องคอมพิวเตอร์เซอร์ฟเวอร์ (Java Application Server เดิมเรียก Java EE ) และการพัฒนาโปรแกรมสำหรับระบบงานแบบฝังตัว เช่น ในเครื่องใช้ไฟฟ้าและอุปกรณ์ IoT (Java Card เดิมเรียก Java ME)
การเรียนรู้การเขียนโปรแกรมภาษาจาวาจะต้องเริ่มจาก Java SE เพื่อเรียนรู้หลักภาษาของภาษาจาวา องค์ประกอบต่างๆในภาษาจาวา และ Java API ดังนั้นเราต้องติดตั้งโปรแกรมชุดพัฒนาภาษาจาวาสำหรับ Java SE หรือที่เรียกว่า Java JDK ( Java Platform, Standard Edition Development Kit ) โดยในชุด JDK ประกอบด้วยโปรแกรมตัวแปลภาษา (Java Compiler) โปรแกรมตรวจสอบและแก้ไขปัญหา (Debuggers) โปรแกรมในการทำเอกสาร (JavaDoc) โปรแกรม JRE โปรแกรม JVM และ Java API
โปรแกรม JRE
JRE ย่อมาจาก Java Runtime Environment เป็นโปรแกรมที่ต้องติดตั้งลงในเครื่องคอมพิวเตอร์ที่ต้องการใช้งานโปรแกรมที่พัฒนาด้วยภาษาจาวา ใน JRE จะประกอบด้วย โปรแกรม Loader โปรแกรม JVM และ Java API โดย โปรแกรม Loader จะทำหน้าที่โหลดโปรแกรมที่เราพัฒนาขึ้นมาให้ไปทำงานบน Java Virtual Machine รวมถึงเชื่อมต่อโปรแกรมที่เราพัฒนาขึ้นมากับ Java API
สำหรับจาวาเวอร์ชั่นไม่เกินเวอร์ชั่น 8 เราสามารถดาวน์โหลดโปรแกรม JRE ได้จากเว็บของ Oracle ที่ url https://www.oracle.com/java/technologies/javase-jre8-downloads.html
แต่สำหรับจาวาเวอร์ชั่น 9 เป็นต้นไป ได้มีการปรับแนวทางในการใช้โปรแกรม JRE โดยให้ผู้พัฒนาโปรแกรมด้วยภาษาจาวาสามารถสร้างโปรแกรม JRE ที่มีเฉพาะโมดูลของ Java API ที่ต้องการได้ เพื่อลดขนาดของโปรแกรมที่จะแจกจ่ายออกไปและลดขนาดการใช้งานหน่วยความจำของเครื่องคอมพิวเตอร์จากการโหลดโมดูลของ Java API ที่ไม่ได้ถูกใช้ในโปรแกรมที่พัฒนาขึ้นมา จึงไม่มีโปรแกรม JRE ให้ดาวน์โหลดอีกต่อไปนับตั้งแต่จาวาเวอร์ชั่น 9 แต่เราสามารถใช้วิธีการติดตั้งโปรแกรม JDK เพราะโปรแกรม JDK มีโปรแกรม JRE ในตัวอยู่แล้ว
หากไม่ต้องการติดตั้งโปรแกรมJDK เราสามารถสร้างโปรแกรม JRE เองได้โดยใช้โปรแกรม jlink ซึ่งเป็นโปรแกรมที่ใช้สร้างโปรแกรม JRE โดยสามารถดูรายละเอียดการใช้งานโปรแกรม jlink ได้จาก https://docs.oracle.com/javase/9/tools/jlink.htm#JSWOR-GUID-CECAC52B-CFEE-46CB-8166-F17A8E9280E9
หรือใช้เครื่องมือจากเว็บ Easy JRE โดยไปที่ url https://justinmahar.github.io/easyjre/ และทำตามขั้นตอนในหน้าเว็บ
โปรแกรม JVM
JVM ย่อมาจาก Java Virtual Machine เป็นโปรแกรมที่ใช้รันไฟล์จาวาไบต์โค๊ดเพื่อแปลงไปเป็นภาษาที่เครื่องคอมพิวเตอร์เข้าใจ โปรแกรม JVM เป็นส่วนหนึ่งของโปรแกรม JRE ไม่สามารถแยกออกมาติดตั้งต่างหากได้ โดยโปรแกรม JVM จะถูกติดตั้งไปพร้อมกับการติดตั้งโปรแกรม JDK หรือโปรแกรม JRE
Java Virtual Machine (JVM) เป็นการจำลองเครื่องคอมพิวเตอร์เพื่อรันโปรแกรมภาษาจาวาที่คอมไพล์เป็นไฟล์จาวาไบต์โค๊ดแล้ว (ไฟล์ที่มีนามสกุล .class) JVM เป็นโปรแกรมที่ทำงานบนระบบปฏิบัติการและจัดเตรียมสภาพแวดล้อมสำหรับโปรแกรมภาษาจาวาที่เราเขียนขึ้นมา เนื่องจากโปรแกรมทำงานอยู่บนเครื่องคอมพิวเตอร์เสมือนจึงสามารถทำงานได้บนฮาร์ดแวร์และระบบปฏิบัติการที่แตกต่างกันตามหลักการ WORA (Write Once Run Anywhere) โปรแกรม JVM ไม่ได้มีเพียงแค่โปรแกรมที่พัฒนาขึ้นมาโดยบริษัทโอราเคิล (Oracle) แต่ยังมีโปรแกรม JVM ที่ถูกพัฒนาขึ้นมาหรือถูกปรับปรุงเพื่อประโยชน์เฉพาะทางอย่างใดอย่างหนึ่งโดยบริษัทอื่นๆด้วย เช่น HotSpot, GraalVM หรือ Azul Zulu อย่างไรก็ตามเพื่อความเข้ากันได้โปรแกรม JVM เหล่านั้นจะถูกพัฒนาโดยอ้างอิง Java Virtual Machine Specification
จากรูปด้านบนไฟล์ที่คอมไพล์แล้วจะมีนามกสุล .class จะถูกโหลดเข้ามาทำงานบน JVM ซึ่ง JVM จะแปลไบต์โค๊ดในไฟล์ไปเป็นภาษาเครื่องอีกทีหนึ่ง ขั้นตอนการทำงานของ JVM ประกอบด้วย
- โหลดไบต์โค๊ด
- ตรวจสอบไบต์โค๊ด
- ใช้งาน (execute) ไบต์โค๊ด
- เตรียมสิ่งแวดล้อมสำหรับการทำงาน
ระบบย่อย Class loader จะทำหน้าที่โหลดไฟล์ไบต์โค๊ดเข้ามาทำงาน ตรวจสอบไบต์โค๊ดด้วยโมดูล bytecode verifier เพื่อให้แน่ใจว่าไม่ได้มีการทำงานอะไรที่อาจจะเป็นอันตราย เช่น พยายามเข้าใช้งานฟิลด์หรือเมธอดที่เป็น private เป็นต้น และจัดเตรียมพื้นที่หน่วยความจำสำหรับไบต์โค๊ด
ระบบย่อย Runtime Data Area เป็นส่วนที่เกี่ยวกับหน่วยความจำของ JVM โดยมีหน้าที่ของส่วนย่อยต่างๆดังนี้
- PC Register เป็นส่วนของหน่วยความจำที่เก็บที่อยู่ในหน่วยความจำของคำสั่งที่กำลังดำเนินการอยู่
- Stack Area เป็นส่วนของหน่วยความจำที่เก็บการเรียกใช้เมธอดและตัวแปร
- Native Method Stack เป็นส่วนของหน่วยความจำเก็บข้อมูลเมธอดที่เป็นภาษาเครื่อง
- Heap เป็นส่วนของหน่วยความจำที่ใช้เก็บออบเจกต์ที่สร้างขึ้นมา
- Method Area เป็นส่วนของหน่วยความจำที่ใช้เก็บข้อมูลในระดับคลาสทั้งหมด เช่น ชื่อคลาส ชื่อคลาสแม่ ข้อมูลของเมธอด และตัวแปร static ทั้งหมด
ทุกเธรดจะมี PC Register, Stack Area และ Native Method Stack เป็นของตัวเอง แต่จะใช้ Heap และ Method Area ร่วมกัน
ระบบย่อย Execute Engine ทำหน้าที่ในการรันโปรแกรมโดยมีหน้าที่ของส่วนย่อยต่างๆดังนี้
- Bytecode Interpreter จะอ่านไบต์โค๊ดขึ้นมาทำงานทีละบรรทัด
- Just in Time compiler (JIT compiler) จะแปลไบต์โค๊ดเป็นภาษาเครื่องก่อนแล้วค่อยทำงานซึ่งจะเร็วกว่า Bytecode Interpreter
- Garbage Collector จะคอยตรวจสอบและส่งคืนหน่วยความจำที่ไม่ถูกใช้งาน
JVM แต่ละยี่ห้ออาจจะใช้ทั้งวิธี Bytecode Interpreter และ Just in Time compiler หรืออย่างใดอย่างหนึ่ง
นอกจากนี้ยังมีส่วนย่อย เช่น Native Method Interface ที่ทำหน้าที่จัดเตรียมส่วนเชื่อมต่อ (interface) กับ Native Method Library ซึ่งประกอบด้วยไฟล์ (C/C++) ที่จำเป็นสำหรับการรันโค้ดในภาษาเครื่อง
Java API
ภาษาจาวาเมื่อถูกสร้างขึ้นมาจะประกอบไปด้วยเฉพาะส่วนที่เป็นพื้นฐานที่จำเป็นสำหรับการเขียนโปรแกรมเชิงวัตถุ ((Object Oriented Programming – OOP) เราอาจจะเรียกส่วนนี้ว่าแก่นของภาษาจาวา (core java) จากนั้นผู้พัฒนาภาษาจาวาจึงเขียนโปรแกรมอื่นๆเพิ่มขึ้นมาด้วยความสามารถของแก่นของภาษาจาวา เพื่อให้ภาษาจาวามีความสามารถที่หลากหลายขึ้น ซึ่งโปรแกรมเหล่านั้นเราเรียกว่า Java API
Java API คือไลบรารี่หรือโปรแกรมพร้อมใช้ที่ผู้พัฒนาภาษาจาวามีมาให้เราใช้งาน Java API ก็เป็นโปรแกรมเชิงวัตถุเพราะถูกสร้างขึ้นมาโดยใช้ภาษาจาวา โดยโปรแกรมจะถูกเขียนเป็นคลาส และคลาสต่างๆใน Java API จะถูกจัดเป็นหมวดหมู่เรียกว่าแพคเกจ และรวบรวมแพคเกจเป็นโมดูลตามลำดับ
จากรูปด้านล่างจะเห็นว่า Java API มีหลายโมดูลมาก และโปรแกรม JRE ตั้งแต่อดีตจนถึงจาวาเวอร์ชั่น 8 จะโหลดโมดูลทั้งหมดนี้เข้าหน่วยความจำของเครื่องคอมพิวเตอร์ทั้งหมดเพื่อเตรียมทำงานกับโปรแกรมที่เขียนด้วยภาษาจาวา จึงเป็นที่มาของการยกเลิกการดาวน์โหลดโปรแกรม JRE ตั้งแต่จาวาเวอร์ชั่น 9 เป็นต้นไปเพื่อให้เราสร้างโปรแกรม JRE เองโดยเลือกเฉพาะโมดูลที่ต้องการใช้งานเท่านั้นเพื่อลดการใช้งานหน่วยความจำโดยไม่จำเป็น
เราสามารถดู Java API ทั้งหมดได้จากเว็บไซต์ https://docs.oracle.com/en/java/javase/17/docs/api/index.html
เราสามารถดูข้อมูลของคลาสต่างๆใน Java API ได้โดยระบุชื่อคลาสที่ต้องการในช่องค้นหา และเลือกคลาสที่ต้องการจากโมดูลและแพคเกจที่ต้องการดู จากตัวอย่างด้านล่างเป็นการค้นหาคลาส System ที่อยู่ในแพคเกจ java.lang
รายละเอียดที่แสดงหลักๆคือคลาสนี้สืบทอดมาจากคลาสใด (ซึ่งเราจะเข้าใจผลจากการสืบทอดมากขึ้นเมื่อได้เรียนเรื่องการสืบทอดของคลาสในบทต่อๆไป) มีคำอธิบายว่าคลาสนี้ทำอะไรได้บ้าง
บอกว่าคลาสนี้มีฟิลด์อะไรบ้าง สามารถเข้าถึงได้แบบไหน
และบอกว่ามีเมธอดอะไรบ้าง สำหรับการใช้งานเมธอด ให้สังเกตุคอลัมภ์ซ้ายสุด (Modifier and Type) ซึ่งเป็นผลลัพธ์ที่ได้จากการใช้เมธอด เช่น void คือไม่มีผลตอบกลับ, static คือ สามารถเรียกใช้เมธอดได้โดยที่ไม่ต้องสร้างออบเจกต์, int หรือ double หรือ primitive data type อื่นๆคือได้ผลลัพธ์เป็นชนิดข้อมูลแบบ primitive data type, String คือได้ผลลัพธ์เป็นออบเจกต์ String, หรือได้ผลลัพธ์เป็นออบเจกต์แบบอื่นๆ เพื่อที่เราจะได้สร้างตัวแปรที่เป็นออบเจกต์แบบเดียวกันมารับค่าไว้ได้ สิ่งที่กล่าวถึงในตอนนี้อาจจะยังไม่เข้าใจว่าพูดถึงอะไร แต่เพื่อเป็นแนวทางสำหรับการเปิดดู Java Doc .ในภายหลัง