เราคุ้นเคยกับความจริงที่ว่า JDK ใหม่จะปรากฏทุกๆ หกเดือนแล้ว จนถึงตอนนี้ แนวทางนี้ได้พิสูจน์ตัวเองแล้ว และความกังวลของนักพัฒนาบางรายว่าพวกเขาจะไม่ตามการอัปเดตนั้นก็เปล่าประโยชน์: มีการเปลี่ยนแปลงเล็กน้อยในช่วงหกเดือนและการเปลี่ยนแปลงดังกล่าวไม่เป็นระดับโลกเหมือนเมื่อก่อน โปรแกรมเมอร์มือใหม่อาจไม่สังเกตเห็นนวัตกรรมเลย
อย่างไรก็ตาม จะดีกว่าสำหรับนักพัฒนาซอฟต์แวร์ในอนาคตที่จะตามทันนวัตกรรมต่างๆ ในบทความนี้ เราจะอธิบายข้อเสนอการขยายเวลา (JEP) ที่ยอมรับตามธรรมเนียม Java 13 มี JEP เพียงห้าตัวและองค์ประกอบไลบรารีหลักใหม่ 76 รายการ (ซึ่งเกือบครึ่งหนึ่งเป็นส่วนเพิ่มเติมอย่างง่าย ๆ ในแพ็คเกจ java.io)
JEP 355 : บล็อกข้อความ (ดูตัวอย่าง)
เริ่มต้นด้วยการเปลี่ยนไวยากรณ์ของภาษา สิ่งที่สำคัญที่สุดคือบล็อกข้อความ ช่วยให้คุณหลีกเลี่ยงการใช้อักขระหลีกและรู้วิธีจัดรูปแบบสตริง คุณอาจจำได้ว่า JDK 12 ไม่ได้รวมคุณสมบัติ Raw String Literals (JEP 326) ที่คาดหวังไว้สำหรับการทำงานกับตัวอักษรสตริง ใน Java 13 มันถูกแทนที่ด้วย JEP 355 ด้วยบล็อกข้อความ คุณคงจำได้ว่าใน Java สตริงจะอยู่ในเครื่องหมายคำพูดคู่ นี่เป็นสิ่งที่ดี แต่ปัญหาคือบรรทัดไม่สามารถครอบครองไฟล์ต้นฉบับได้มากกว่าหนึ่งบรรทัด (เพื่อหลีกเลี่ยงความสับสนกับบรรทัด Java ในที่นี้เราจะเรียกบรรทัดไฟล์ว่า "บรรทัด") มาดูรอบๆ และใช้สัญลักษณ์กัน\n
หากจำเป็นต้องมีตัวแบ่ง หรือการต่อนิพจน์หลายบรรทัดเข้า ด้วยกัน มันออกมาไม่ดีนัก! ตัวอักษรข้อความที่มีแฟรกเมนต์ HTML, XML, SQL หรือ JSON ที่ฝังไว้นั้นยุ่งยากเป็นพิเศษ การ Escape การต่อข้อมูล และการแก้ไขด้วยตนเองทั้งหมดนี้ ทำให้การเขียนโค้ดไม่สะดวกและอ่านยาก บล็อกข้อความพยายามแก้ไขปัญหานี้ พวกเขาเริ่ม เอ่อ... ด้วยเครื่องหมายคำพูดสามเท่าและลงท้ายด้วย (ฉันรู้ มันฟังดูไม่ค่อยดีนัก) ทุกอย่างระหว่างเครื่องหมายคำพูดจะถูกตีความว่าเป็นส่วนหนึ่งของบรรทัด รวมถึงการขึ้นบรรทัดใหม่ด้วย บล็อกข้อความสามารถใช้ได้เหมือนกันทุกประการกับตัวอักษรข้อความมาตรฐาน และ Java จะคอมไพล์โค้ดในลักษณะเดียวกัน เครื่องหมายคำพูดเปิดต้องตามด้วยตัวคั่นบรรทัด บล็อกข้อความไม่สามารถใช้ในบรรทัดเดียวได้ ดังนั้นโค้ด
String smallBlock = """Only one line""";
จะทำให้เกิดข้อผิดพลาดดังต่อไปนี้:
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
ตอนนี้สามารถเขียนส่วนย่อย HTML อย่างง่ายได้ดังนี้:
String htmlBlock = """
<html>
<body>
<p>CodeGym Web page</p>
</body>
<html>
""";
เรามาพูดถึงรายละเอียดปลีกย่อยบางประการที่ควรระวังเมื่อใช้บล็อกข้อความ การวางตำแหน่งของเครื่องหมายคำพูดปิดมีความสำคัญ เนื่องจากเป็นตัวกำหนดวิธีจัดการกับช่องว่างเป็นครั้งคราว ในตัวอย่างข้างต้น เครื่องหมายคำพูดปิดจะสอดคล้องกับการเยื้องของข้อความ HTML ในกรณีนี้ คอมไพเลอร์จะลบช่องว่างการเยื้องออก และด้วยเหตุนี้ เราจึงได้บรรทัดดังนี้:
<html>
<body>
<p>My web page</p>
</body>
</html>
บันทึก:บรรทัดดังกล่าวจะมีการขึ้นบรรทัดใหม่ที่ท้ายบรรทัด หากไม่จำเป็น คุณสามารถใส่เครื่องหมายคำพูดปิด “”” ไว้หลังแท็ก </html> ได้โดยตรง หากเราย้ายเครื่องหมายคำพูดปิดใกล้กับระยะขอบด้านซ้าย สิ่งนี้จะเปลี่ยนจำนวนการเยื้องที่ถูกลบออก หากเราย้ายช่องว่างทั้งสองไปทางซ้าย เราจะเพิ่มช่องว่างสองช่องสำหรับการเยื้องในแต่ละบรรทัด การย้ายไปที่ขอบด้านซ้ายจะทำให้ช่องว่างภายในทั้งหมดยังคงอยู่ การย้ายเครื่องหมายคำพูดไปทางขวาจะไม่มีผลใดๆ และจะไม่เพิ่มการเยื้องอีกต่อไป บล็อกข้อความถูกรวมอยู่ใน JDK 13 เป็นคุณลักษณะการแสดงตัวอย่าง ซึ่งหมายความว่ายังไม่ได้รวมอยู่ในข้อกำหนดภาษา Java ที่เกี่ยวข้อง กล่าวคือยังไม่ชัดเจนว่าคุณลักษณะนี้จะกลายเป็นส่วนถาวรของภาษาหรือเป็นเพียงแขกที่นี่ ขณะนี้นักพัฒนาซอฟต์แวร์สามารถทดสอบคุณลักษณะนี้และแสดงความคิดเห็นได้ ชะตากรรมของบล็อกข้อความจะขึ้นอยู่กับมัน: สามารถปรับปรุงคุณสมบัติได้และหากคุณไม่ชอบก็สามารถลบออกทั้งหมดได้ หากคุณต้องการลองใช้บล็อกข้อความในทางปฏิบัติ โปรดจำไว้ว่าต้องรวมคุณสมบัติการแสดงตัวอย่างไว้อย่างชัดเจนเพื่อที่จะคอมไพล์และรัน การรวบรวม:
javac --enable-preview --release 13 TextBlock.java
หากต้องการเรียกใช้แอปพลิเคชัน คุณต้องเปิดใช้งานคุณลักษณะการแสดงตัวอย่าง:
java --enable-preview TextBlock
ชั้นเรียนString
มีวิธีการใหม่สามวิธีที่ช่วยเสริมการเปลี่ยนแปลงภาษานี้:
formatted()
: จัดรูปแบบสตริงโดยใช้ตัวสตริงเองเป็นสตริงรูปแบบ เทียบเท่ากับความท้าทายformat(this, args)
stripIndent()
: ลบช่องว่างแบบสุ่มออกจากสตริง สิ่งนี้มีประโยชน์หากคุณกำลังอ่านสตริงหลายบรรทัดและต้องการใช้การยกเว้นช่องว่างแบบเดียวกับที่คุณทำกับการประกาศอย่างชัดเจนtranslateEscapes()
: ส่งคืนสตริงที่มีลำดับหลีก (เช่น\ r
) ซึ่งแปลเป็นค่า Unicode ที่เหมาะสม
@PreviewFeature
อาจช่วยในสถานการณ์ดังกล่าวได้ แต่ยังไม่รวมอยู่ใน JDK (แม้ว่าจะมีความเป็นไปได้สูงที่จะปรากฏอยู่ใน JDK 14)
JEP 354 : สลับนิพจน์ (ดูตัวอย่าง)
Java 12 แนะนำข้อเสนอสำหรับรูปแบบการเขียนนิพจน์ใหม่พร้อมคำสั่ง switch - JEP 325 กลายเป็นคุณสมบัติแสดงตัวอย่างแรกสุด และชะตากรรมของมันพิสูจน์ให้เห็นว่าการส่งข้อเสนอให้กับผู้ใช้เป็นความคิดที่ดี ก่อนหน้า JDK 12switch
สามารถใช้เป็นคำสั่งที่ดำเนินการได้เท่านั้น แต่จะไม่ส่งคืนผลลัพธ์ แต่ใน Java 12 อนุญาตให้ใช้switch
เป็นนิพจน์ที่ส่งคืนผลลัพธ์ที่สามารถกำหนดให้กับตัวแปรได้ มีการเปลี่ยนแปลงอื่น ๆ ในไวยากรณ์ของคำสั่ง case ภายในswitch
. ลองดูตัวอย่างจาก JEP เพื่อทำความเข้าใจวิธีการทำงาน
int numberOfLetters;
switch(dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numberOfLetter = 6;
break;
case TUESDAY
numberOfLetter = 7;
break;
case THURSDAY
case SATURDAY
numberOfLetter = 8;
break;
case WEDNESDAY
numberOfLetter = 9;
break;
default:
throw new IllegalStateException("Huh?: " + day);
}
ในตัวอย่างนี้ เราใช้ค่าdayOfWeek
เพื่อกำหนดค่าให้numberOfLetters
กับ เนื่องจากลักษณะเฉพาะของงานของผู้ปฏิบัติงานswitch
รหัสนี้ไม่ได้สวยงามที่สุดและง่ายต่อการทำผิดพลาด ขั้นแรก ถ้าเราลืมใช้คำสั่งbreak
กับแต่ละกลุ่มของป้ายกำกับเคส เราจะตั้งค่าเริ่มต้นให้กับกลุ่มของป้ายกำกับเคสถัดไป สิ่งนี้สามารถนำไปสู่ข้อผิดพลาดที่ยากต่อการค้นหา ประการที่สอง เราต้องกำหนดป้ายกำกับเคสแต่ละกลุ่ม ถ้าเราลืมแน่นอนว่าเราจะได้รับข้อผิดพลาดของคอมไพเลอร์ แต่ตัวเลือกนี้ไม่เหมาะเช่นกัน โค้ดของเราค่อนข้างละเอียดเพราะแต่ละค่าdayOfWeek
ต้องมีป้ายกำกับตัวพิมพ์ของตัวเอง เมื่อใช้ไวยากรณ์ใหม่ เราจะได้โค้ดที่สะอาดตามากขึ้นและมีข้อผิดพลาดน้อยลง:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Huh?: " + day);
};
ตอนนี้เราจำเป็นต้องทำการมอบหมายงานเพียงครั้งเดียว (จากค่าที่ส่งคืนของนิพจน์switch
) และสามารถใช้รายการที่คั่นด้วยเครื่องหมายจุลภาคสำหรับป้ายกำกับเคสได้ และเนื่องจากเราไม่ได้ใช้โอเปอเรเตอร์break
เราจึงขจัดปัญหาที่เกี่ยวข้องได้ ไวยากรณ์นิพจน์switch
ช่วยให้เราสามารถใช้ไวยากรณ์สไตล์เก่าได้ ดังนั้นใน JDK 12 เราสามารถเขียนได้ดังนี้:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
break 6;
case TUESDAY
break 7;
case THURSDAY
case SATURDAY
break 8;
case WEDNESDAY
break 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
ตามชุมชน Java การใช้การโอเวอร์โหลดbreak
เพื่อระบุค่าที่ส่งคืนอาจทำให้เกิดความสับสน ภาษา Java ยังอนุญาตให้คุณใช้break
( และcontinue
) กับป้ายกำกับ เช่น ตัวดำเนินการข้ามแบบไม่มีgoto
เงื่อนไข JEP 354 เปลี่ยนการใช้งานนี้break
ดังนั้นใน Java 13 รหัสของเราจึงเปลี่ยนแปลงเล็กน้อย:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
yield 6;
case TUESDAY
yield 7;
case THURSDAY
case SATURDAY
yield 8;
case WEDNESDAY
yield 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
JEP สามรายการถัดไปเชื่อมโยงกับ Java Virtual Machine
ไฟล์เก็บถาวร CDS ไดนามิกJEP 350
ส่วนขยายนี้ช่วยให้คุณสามารถเก็บถาวรคลาสแบบไดนามิกเมื่อสิ้นสุดการทำงานของแอปพลิเคชัน Java CDS หรือการแบ่งปันข้อมูลคลาสช่วยให้คุณสามารถแพ็คคลาสทั้งหมดที่เปิดใช้งานเมื่อเริ่มต้นระบบลงในไฟล์เก็บถาวรพิเศษclass data sharing
โดยใช้รายการคลาสเดียวกันเหล่านี้เป็นค่าเริ่มต้น สิ่งนี้นำไปสู่การเร่งความเร็วที่สำคัญในการเปิดแอปพลิเคชันและประหยัด RAM ก่อนหน้านี้ การใช้ AppCDS เป็นกระบวนการหลายขั้นตอนที่เกี่ยวข้องกับการสร้างรายการคลาสที่เกี่ยวข้อง และใช้รายการนั้นเพื่อสร้างไฟล์เก็บถาวรที่จะใช้สำหรับการเรียกใช้ครั้งต่อไป ตอนนี้สิ่งที่จำเป็นต้องมีคือการเปิดตัวแอปพลิเคชันเพียงครั้งเดียวโดยมีแฟล็ก -XX: ArchiveClassesAtExit
ระบุตำแหน่งที่จะเขียนไฟล์เก็บถาวร ด้วยแนวทางนี้ คลาสจะถูกรวมเข้าไว้ในไฟล์เก็บถาวรโดยอัตโนมัติหลังจากที่แอปพลิเคชันหยุดทำงานตามปกติ
JEP 351 ZGC : ยกเลิกการผูกมัดหน่วยความจำที่ไม่ได้ใช้
ปีที่แล้วJDK 11ได้เปิดตัว ZGC ซึ่งเป็นเครื่องรวบรวมขยะรุ่นทดลอง ปรับขนาดได้ และมีเวลาแฝงต่ำ ในตอนแรก ZGC มีพฤติกรรมค่อนข้างแปลก: ไม่อนุญาตให้หน่วยความจำส่งคืนไปยังระบบปฏิบัติการแม้ว่าจะไม่จำเป็นอีกต่อไปก็ตาม สำหรับสภาพแวดล้อมบางอย่าง เช่น คอนเทนเนอร์ ซึ่งบริการต่างๆ ใช้งานทรัพยากรในเวลาเดียวกัน อาจจำกัดความสามารถในการขยายขนาดและประสิทธิภาพของระบบ ฮีป ZGC ประกอบด้วยสิ่งที่เรียกว่า ZPages เมื่อ ZPages ถูกล้างระหว่างรอบการรวบรวมขยะ ZPages เหล่านั้นจะถูกส่งกลับไปยัง ZPageCache ZPages ในแคชนี้เรียงลำดับตามความถี่ในการใช้งาน ใน Java 13 นั้น ZGC จะส่งคืนเพจที่ถูกระบุว่าไม่ได้ใช้งานเป็นเวลานานไปยังระบบปฏิบัติการ วิธีนี้สามารถนำกลับมาใช้ใหม่สำหรับกระบวนการอื่นได้JEP 353ปรับใช้ Socket API เดิมอีกครั้ง
การใช้งาน API ทั้งสอง ยังคงjava.net.Socket
เป็นjava.net.ServerSocket
JDK 1.0 ในที่นี้และ JDK ที่ตามมาทั้งหมด การใช้งาน API เหล่านี้ใช้เทคนิคหลายอย่าง (เช่น การใช้เธรดสแต็กเป็นบัฟเฟอร์ I/O) ซึ่งทำให้ไม่ยืดหยุ่นและบำรุงรักษายาก เพื่อแก้ไขปัญหานี้ มีการจัดเตรียมการใช้งานใหม่ใน JDK NioSocketImpl
13 ไม่ต้องใช้โค้ดเนทีฟอีกต่อไป ทำให้ง่ายต่อการพอร์ตไปยังแพลตฟอร์มต่างๆ คลาสนี้ยังใช้กลไกแคชบัฟเฟอร์ที่มีอยู่ (หลีกเลี่ยงการใช้เธรดสแต็กเพื่อจุดประสงค์นี้) และการล็อคjava.util.concurrent
แทนที่จะใช้วิธีซิงโครไนซ์ สิ่งนี้จะทำให้การรวมเข้ากับไฟเบอร์จากProject Loom ง่าย ขึ้น
API ใหม่
เราได้กล่าวไว้ก่อนหน้านี้ว่า Java 13 มี API ใหม่ 76 รายการในไลบรารีคลาสพื้นฐาน ครอบคลุมพื้นที่ต่อไปนี้:- การอัปเดตการสนับสนุน Unicode
- สามวิธีใหม่
String
เพื่อรองรับบล็อกข้อความ (ดูคำอธิบาย JEP 255 ด้านบน) - คลาส
java.nio
ตอนนี้มีแบบสัมบูรณ์ (ตรงข้ามกับแบบสัมพันธ์)get
และกำหนดวิธีการ เช่นเดียวกับคลาสนามธรรมพื้นฐาน Buffer
ที่รวมวิธีslice()
การดึงข้อมูลส่วนหนึ่งของบัฟเฟอร์ - วิธี
force()
การเรียนMappedByteBuffer
บังคับให้ส่วนบัฟเฟอร์ถูกเขียนไปยังหน่วยเก็บข้อมูลสำรอง nio.FileSystem
เพิ่มรูปแบบโอเวอร์โหลดใหม่สามรูปแบบnewFileSystem()
สำหรับการเข้าถึงเนื้อหาของไฟล์เป็นระบบไฟล์- มี วิธีการใหม่ที่น่าสนใจ
javax.annotation.processing.ProcessingEnvironment
เกิดขึ้นisPreviewEnabled()
. มันจะบอกคุณว่าเปิดใช้งานคุณสมบัติการแสดงตัวอย่างหรือไม่ สิ่งนี้น่าสนใจเนื่องจากคำอธิบายประกอบที่กล่าวถึงข้างต้น@PreviewFeature
จะไม่สามารถใช้ได้จนกว่า JDK 14 จะออก DocumentBuilderFactory
และSAXParserFactory
รับjavax.xml.parsers
วิธีการใหม่สามวิธีในการสร้างอินสแตนซ์ที่รับรู้เนมสเปซ
GO TO FULL VERSION