Java ได้ผ่านการเปลี่ยนแปลงอย่างน่าทึ่งตั้งแต่เริ่มต้น ก้าวจากการเป็นภาษาเชิงวัตถุแบบเรียบง่ายไปสู่แพลตฟอร์มที่อุดมไปด้วยฟีเจอร์ การทบทวนล่าสุดที่ให้คะแนนการเปลี่ยนแปลงของ Java ตลอด 26 ปี ได้จุดประกายการอภิปรายอย่างเร่าร้อนในหมู่ Developer เกี่ยวกับว่าฟีเจอร์ใดที่เพิ่มประสิทธิภาพให้ภาษาจริงๆ และฟีเจอร์ใดที่ทำไม่สำเร็จ การอภิปรายในชุมชนเผยให้เห็นความแตกแยกอย่างลึกซึ้งในทุกเรื่อง ตั้งแต่ Annotation และ Stream ไปจนถึงระบบ Module ที่ถกเถียงกันอย่างกว้างขวาง
ความแตกแยกเรื่อง Annotation: การลดโค้ดซ้ำซ้อน vs ฝันร้ายในการดีบัก
Annotation ได้กลายมาเป็นหนึ่งในฟีเจอร์ที่ก่อให้เกิดความเห็นต่างมากที่สุดของ Java ตั้งแต่เปิดตัวใน Java 5 ในขณะที่ Developer บางส่วนมองว่ามันจำเป็นสำหรับการลดโค้ดแบบเดิมๆ ซ้ำๆ คนอื่นๆ มองว่ามันเป็นเหมือนคาถาลึกลับที่บดบังตรรกะของแอปพลิเคชัน การอภิปรายมุ่งเน้นไปที่ว่าการใช้ Annotation ทำให้การพัฒนาง่ายขึ้นหรือสร้างความท้าทายในการดีบัก
การยอมรับอย่างกว้างขวางของ Spring Framework แสดงให้เห็นถึงพลังของ Annotation สำหรับการเขียนโปรแกรมแบบประกาศ (Declarative Programming) ดังที่ Developer คนหนึ่งระบุว่า ฉันต้องการรันงานตามกำหนดเวลา เพียงใช้ @EnableScheduling แล้วตามด้วย @Scheduled(cron = 'xxxxxx') - เสร็จแล้ว แนวทางนี้ช่วยลดโค้ดการกำหนดค่าซ้ำๆ แต่ก็มาพร้อมกับต้นทุน ผู้วิจารณ์แย้งว่าโค้ดที่ใช้ Annotation จำนวนมากจะทำให้การดีบักและการบำรุงรักษายากขึ้น โดยเฉพาะเมื่อต้องการเปลี่ยนการกำหนดค่าผ่านสภาพแวดล้อมต่างๆ โดยไม่ต้องคอมไพล์ใหม่
ฉันชอบโค้ดแบบเรียบง่ายตรงไปตรงมา ที่เรียกใช้ฟังก์ชันบางอย่าง มากกว่าการใช้เวทมนตร์แบบประกาศนี้ทุกวัน
การอภิปรายเกี่ยวกับ Annotation สะท้อนถึงความตึงเครียดพื้นฐานในการพัฒนา Java สมัยใหม่ ระหว่างความสะดวกสบายและความชัดเจน ในขณะที่ Annotation ช่วยให้เฟรมเวิร์กที่มีประสิทธิภาพเช่น Spring เติบโตได้ มันก็สร้างสิ่งที่ Developer บางส่วนอธิบายว่าเป็น โค้ดขยะ ที่เข้าใจได้เฉพาะเมื่อรันแอปพลิเคชันจริงๆ
ฟีเจอร์ที่ถกเถียงกันมากที่สุดใน Java (จากการสนทนาในชุมชน)
- Java 9 Modules: ถูกวิพากษ์วิจารณ์อย่างกว้างขวางว่ามีความซับซ้อนแต่ให้ประโยชน์น้อยมาก
- Java 8 Streams: มีความเห็นแตกต่างกันระหว่างพลังในการแสดงออกกับความซับซ้อนในการดีบัก
- Annotations: มีการถอดเถียงระหว่างการลดโค้ดซ้ำซ้อนกับโค้ดที่ทำงานแบบ "มหัศจรรย์" ที่เข้าใจยาก
- Checked Exceptions: มีการอภิปรายอย่างต่อเนื่องว่าเป็นแนวคิดที่ล้มเหลวหรือเป็นฟีเจอร์ที่มีประโยชน์
Stream และ Lambda: การก้าวเข้าสู่การเขียนโปรแกรมเชิงฟังก์ชันที่ยังคงเป็นที่ถกเถียง
การเปิดตัว Lambda และ Stream ใน Java 8 แสดงถึงก้าวที่กล้าหาญของภาษานี้สู่การเขียนโปรแกรมเชิงฟังก์ชัน แต่การนำไปใช้ยังคงแบ่งแยก Developer มาหลายปี ผู้สนับสนุนยกย่อง Stream ที่ช่วยให้การประมวลผลคอลเลกชันแสดงออกได้มากขึ้น ในขณะที่ผู้วิจารณ์ชี้ให้เห็นถึงความยากในการดีบักและข้อกังวลด้านประสิทธิภาพ
ความซับซ้อนของ Streams API มาจากจุดประสงค์สองอย่าง - ออกแบบมาทั้งสำหรับการเขียนโปรแกรมแบบสไตล์ฟังก์ชันและการทำให้ขนานกันได้ง่าย สิ่งที่บางคนอธิบายว่า การขยายขอบเขต นี้ ส่งผลให้ API ที่ดีบักได้ยากและแทบไม่เคยถูกใช้สำหรับความสามารถในการทำงานแบบขนาน Developer จำนวนมากรายงานว่า Parallel Stream ถูกใช้งานจริงน้อยมาก ในขณะที่ Sequential Stream มาพร้อมกับโอเวอร์เฮดที่สำคัญใน Stack Trace และการใช้งานหน่วยความจำ
แม้จะมีการวิจารณ์ Streams ได้เปลี่ยนแปลงพื้นฐานวิธีที่ Developer Java จำนวนมากเข้าถึงการประมวลผลคอลเลกชัน สไตล์การเขียนแบบฟังก์ชันได้พิสูจน์แล้วว่ามีเสน่ห์น่าดึงดูดจน Developer บางส่วนรู้สึก คิดถึง Streams API เมื่อเขียน Go นี่ชี้ให้เห็นว่าแม้การนำไปใช้อาจมีข้อบกพร่อง แต่แนวคิดนี้ตอบสนองความต้องการที่แท้จริงของ Developer สำหรับการประมวลผลข้อมูลแบบประกาศมากขึ้น
ฟีเจอร์ Java ที่ได้รับการประเมินสูง
- Try-with-resources (Java 7): 10/10 สำหรับความปลอดภัยในการจัดการ exception
- Records (Java 14): 10/10 สำหรับการทำให้ data class เรียบง่ายขึ้น
- java.util.concurrent (Java 5): 10/10 สำหรับเครื่องมือ concurrency ที่ออกแบบมาอย่างดี
- java.time (Java 8): 8/10 สำหรับการแก้ไขปัญหาการจัดการวันที่และเวลา
- Local type inference (Java 10): 9/10 สำหรับการลดความซับซ้อนของโค้ด
ความผิดพลาดของระบบ Module และวิวัฒนาการแบบอนุรักษนิยมของ Java
ระบบ Module ของ Java 9 เป็นหนึ่งในการเพิ่มเติมที่ถูกวิจารณ์ในทางลบมากที่สุดของภาษา Developer ให้คะแนนมันต่ำอย่างสม่ำเสมอ โดยมีความคิดเห็นตั้งแต่ การเปลี่ยนแปลงครั้งใหญ่เพื่อประโยชน์ที่จับต้องได้น้อยมาก ไปจนถึงให้ คะแนนศูนย์ ในการให้คะแนนฟีเจอร์ ระบบ Module มีเจตนาเพื่อปรับปรุงโครงสร้างและความปลอดภัยของแอปพลิเคชัน แต่แทนที่จะสร้างความซับซ้อนโดยไม่มีข้อได้เปรียบที่ชัดเจนสำหรับ Developer แอปพลิเคชันส่วนใหญ่
แนวทางอนุรักษนิยมของ Java ต่อวิวัฒนาการของภาษาได้รับคำวิจารณ์ที่หลากหลายในการอภิปรายของชุมชน Developer บางส่วนชื่นชันความเสถียรและความเข้ากันได้ย้อนหลังของภาษา โดยระบุว่า มีไลบรารีที่เกิดการเปลี่ยนแปลงแบบทำลาย (Breaking Changes) ในปีนี้มากกว่าที่ภาษาโปรแกรม Java มีมาตลอด 17 รีลีสที่ผ่านมาเสียอีก คนอื่นๆ แสดงความหงุดหงิดที่ Java มักนำฟีเจอร์ที่พิสูจน์แล้วจากภาษาอื่นๆ ไปใช้ในวิธีที่ด้อยกว่า สร้างสิ่งที่ผู้แสดงความคิดเห็นคนหนึ่งเรียกว่า Frankenstein's Monster ที่มีทั้งความสวยงามและเสน่ห์พอๆ กัน
ความตึงเครียดระหว่างนวัตกรรมและความเสถียรกำหนดวิวัฒนาการของ Java ในขณะที่ภาษาที่ใหม่กว่าสามารถนำฟีเจอร์ไปใช้ได้อย่างก้าวร้าวมากขึ้น Java ต้องสร้างสมดุลระหว่างความสามารถใหม่กับโค้ดที่มีอยู่หลายทศวรรษ นี่อธิบายว่าทำไมฟีเจอร์เช่น Local Type Inference (var) ใช้เวลานานมากถึงจะมาถึง และทำไมการนำไปใช้ของพวกมันจึงมักรวมถึงการประนีประนอมที่ผู้ที่ชอบความบริสุทธิ์อาจไม่ชอบ
ไทม์ไลน์การเปิดตัว Java และฟีเจอร์สำคัญ
- Java 5 (2004): Generics, Annotations, Autoboxing, Enums
- Java 7 (2011): Try-with-resources, Diamond operator
- Java 8 (2014): Lambdas, Streams, java.time
- Java 9 (2017): Module system
- Java 14 (2020): Records, Pattern matching instanceof
- Java 21 (2023): Virtual threads, String templates (preview)
เรื่องความสำเร็จเงียบๆ ของ Java สมัยใหม่
ท่ามกลางข้อโต้แย้ง ฟีเจอร์ Java หลายอย่างได้รับคำชมเชยเกือบจะเป็นสากลจากชุมชน Developer แพ็คเกจ java.time ที่เปิดตัวใน Java 8 แก้ไขข้อร้องเรียนที่มีมายาวนานเกี่ยวกับการจัดการวันที่และเวลา Try-with-resources ที่เพิ่มใน Java 7 ปรับปรุงความปลอดภัยจากข้อผิดพลาด (Exception Safety) และการจัดการทรัพยากรได้อย่างมาก Records ที่เปิดตัวใน Java 14 ในที่สุดก็ให้วิธีที่กระชับสำหรับ Java ในการกำหนดตัวนำข้อมูล (Data Carriers)
ฟีเจอร์ที่ประสบความสำเร็จเหล่านี้มีลักษณะร่วมกัน: พวกมันแก้ไขจุดที่สร้างความเจ็บปวดได้ชัดเจนโดยไม่นำความซับซ้อนที่มากเกินไปมา และพวกมันรวมเข้ากับกระบวนทัศน์ Java ที่มีอยู่ได้ดี ดังที่ Developer คนหนึ่งระบุเกี่ยวกับ Try-with-resources ว่า ฉันทำงานกับ Java มาเป็นปีและเพิ่งรู้ว่ามีสิ่งนี้อยู่เมื่อไม่นานมานี้ ฉันคิดว่ามันต้องค่อนข้างใหม่ 14 ปีแล้ว! นี่ชี้ให้เห็นว่าแม้แต่ฟีเจอร์ที่ประสบความสำเร็จมากที่สุดของ Java บางครั้งก็ใช้เวลาหลายปีเพื่อได้รับการยอมรับในวงกว้าง
การยอมรับ Records ของชุมชนและความระมัดระวังต่อ Modules แสดงให้เห็นว่า Developer Java ให้คุณค่ากับการปรับปรุงที่ใช้งานได้จริงมากกว่าการปฏิวัติเชิงสถาปัตยกรรม ฟีเจอร์ที่ทำให้งานทั่วไปง่ายขึ้นโดยไม่บังคับให้เกิดการเปลี่ยนแปลงโครงสร้างหลักมักได้รับการต้อนรับอย่างอบอุ่นที่สุดในระบบนิเวศ Java
วิวัฒนาการของ Java ยังคงจุดประกายการอภิปรายอย่างแข็งขันเพราะ Developer ใส่ใจอย่างลึกซึ้งกับเครื่องมือที่พวกเขาใช้ทุกวัน การนำฟีเจอร์จากภาษาที่ใหม่กว่ามาใช้อย่างค่อยเป็นค่อยไปของภาษาแสดงให้เห็นทั้งประโยชน์และข้อจำกัดของวิวัฒนาการแบบอนุรักษนิยม ในขณะที่ Java อาจไม่เคยทำให้ Developer ที่ชอบนวัตกรรมที่รุนแรงกว่าพอใจได้ การปรับปรุงอย่างมั่นคงของมันก็รักษาตำแหน่งให้เป็นหนึ่งในภาษาโปรแกรมที่ใช้กันอย่างแพร่หลายที่สุดในโลก การอภิปรายของชุมชนอย่างต่อเนื่องทำให้มั่นใจได้ว่าฟีเจอร์ Java ในอนาคตจะยังคงสะท้อนความต้องการที่แท้จริงของ Developer มากกว่าแค่อุดมคติทางทฤษฎีล้วนๆ
อ้างอิง: Rating 26 years of Java changes