จาวา 8
อินเตอร์เฟซการทำงาน
นี่คืออะไร? ส่วนต่อประสานการทำงานคือส่วนต่อประสานที่มีวิธีหนึ่งที่ไม่ได้นำไปใช้ (นามธรรม) @FunctionalInterfaceเป็นคำอธิบายประกอบที่เป็นทางเลือกซึ่งวางไว้เหนืออินเทอร์เฟซดังกล่าว จำเป็นต้องตรวจสอบว่าเป็นไปตามข้อกำหนดของอินเทอร์เฟซการทำงานหรือไม่ (มีวิธีนามธรรมเพียงวิธีเดียว) แต่เช่นเคย เรามีคำเตือนบางประการ: วิธีการเริ่มต้นและแบบคงที่ไม่อยู่ภายใต้ข้อกำหนดเหล่านี้ ดังนั้นจึงอาจมีวิธีการดังกล่าวได้หลายวิธี + หนึ่งวิธีนามธรรมและอินเทอร์เฟซจะทำงานได้ นอกจากนี้ยังอาจมีวิธีการของคลาส Object ที่ไม่ส่งผลกระทบต่อคำจำกัดความของอินเทอร์เฟซตามการทำงาน ฉันจะเพิ่มคำสองสามคำเกี่ยวกับวิธีการเริ่มต้นและแบบคงที่:-
เมธอดที่มี ตัวปรับแต่ง เริ่มต้นทำให้คุณสามารถเพิ่มเมธอดใหม่ให้กับอินเทอร์เฟซได้โดยไม่ทำให้การใช้งานที่มีอยู่เสียหาย
public interface Something { default void someMethod { System.out.println("Some text......"); } }
ใช่ ใช่ เราเพิ่มวิธีการที่นำไปใช้ในอินเทอร์เฟซ และเมื่อนำวิธีนี้ไปใช้ คุณไม่สามารถแทนที่ได้ แต่ใช้เป็นวิธีการที่สืบทอดมา แต่ถ้าคลาสใช้อินเทอร์เฟซสองตัวด้วยวิธีการที่กำหนด เราจะมีข้อผิดพลาดในการคอมไพล์ และหากคลาสใช้อินเทอร์เฟซและสืบทอดคลาสด้วยวิธีการที่เหมือนกัน วิธีการระดับพาเรนต์จะทับซ้อนวิธีการอินเทอร์เฟซและข้อยกเว้นจะไม่ทำงาน
-
วิธีการคงที่ในอินเทอร์เฟซทำงานเหมือนกับ วิธีการ คงที่ในชั้นเรียน อย่าลืมว่าคุณไม่สามารถสืบทอด วิธีการ แบบคงที่ได้เช่นเดียวกับที่คุณไม่สามารถเรียก วิธีแบบ คงที่จากคลาสที่สืบทอดได้
-
Consumer - รับอาร์กิวเมนต์ประเภท T โดยไม่ส่งคืนสิ่งใดเลย (เป็นโมฆะ)
ตัวอย่าง:
void someMethod(T t);
-
ซัพพลายเออร์ - ไม่ต้องการสิ่งใดเป็นอินพุต แต่จะคืนค่าบางค่า T
ตัวอย่าง:
T someMethod();
-
ฟังก์ชัน - รับพารามิเตอร์ประเภท T เป็นอินพุต ส่งคืนค่าประเภท R
ตัวอย่าง:
R someMethod(T t);
-
UnaryOperator - รับอาร์กิวเมนต์ T และส่งคืนค่าประเภท T
ตัวอย่าง:
T someMethod(T t);
ภาคแสดง - รับค่า T บางส่วนเป็นอาร์กิวเมนต์ ส่งคืนบูลีน
ตัวอย่าง:boolean someMethod(T t);
ลำธาร
สตรีมเป็นวิธีการจัดการโครงสร้างข้อมูลในรูปแบบการทำงาน โดยทั่วไปแล้วสิ่งเหล่านี้คือคอลเลกชัน (แต่คุณสามารถใช้ในสถานการณ์อื่นที่ไม่ค่อยพบบ่อยได้) ในภาษาที่เข้าใจได้ง่ายขึ้น Stream คือสตรีมข้อมูลที่เราประมวลผลราวกับทำงานกับข้อมูลทั้งหมดในเวลาเดียวกัน และไม่ใช่การบังคับอย่างดุเดือดเหมือนกับ for-each ลองดูตัวอย่างเล็กๆ น้อยๆ สมมติว่าเรามีชุดตัวเลขที่เราต้องการกรอง (น้อยกว่า 50) เพิ่มขึ้น 5 และส่งออกตัวเลข 4 ตัวแรกจากตัวเลขที่เหลือไปยังคอนโซล เราจะทำสิ่งนี้ก่อนหน้านี้ได้อย่างไร:List<Integer> list = Arrays.asList(46, 34, 24, 93, 91, 1, 34, 94);
int count = 0;
for (int x : list) {
if (x >= 50) continue;
x += 5;
count++;
if (count > 4) break;
System.out.print(x);
}
ดูเหมือนจะมีโค้ดไม่มากนัก และตรรกะก็ดูสับสนเล็กน้อยอยู่แล้ว มาดูกันว่ามันจะดูเป็นอย่างไรเมื่อใช้สตรีม:
Stream.of(46, 34, 24, 93, 91, 1, 34, 94)
.filter(x -> x < 50)
.map(x -> x + 5)
.limit(4)
.forEach(System.out::print);
สตรีมทำให้ชีวิตง่ายขึ้นอย่างมากโดยการลดจำนวนโค้ดและทำให้อ่านง่ายขึ้น สำหรับผู้ที่ต้องการเจาะลึกหัวข้อนี้โดยละเอียด นี่คือบทความที่ดี (ฉันอยากจะบอกว่ายอดเยี่ยมด้วยซ้ำ) ในหัวข้อนี้
แลมบ์ดา
บางทีคุณลักษณะที่สำคัญที่สุดและรอคอยมานานก็คือรูปลักษณ์ของแลมบ์ดา แลมบ์ดาคืออะไร? นี่คือบล็อกของโค้ดที่สามารถส่งผ่านไปยังที่ต่างๆ เพื่อให้สามารถดำเนินการได้ในภายหลังได้บ่อยเท่าที่ต้องการ ฟังดูน่าสับสนใช่ไหม? พูดง่ายๆ ก็คือการใช้ lambdas คุณสามารถใช้วิธีการของอินเทอร์เฟซการทำงานได้ (ประเภทของการใช้งานคลาสที่ไม่ระบุชื่อ):Runnable runnable = () -> { System.out.println("I'm running !");};
new Thread(runnable).start();
เราใช้เมธอด run() อย่างรวดเร็วและไม่มีกฎเกณฑ์ที่ไม่จำเป็น และใช่: Runnable เป็นอินเทอร์เฟซที่ใช้งานได้ ฉันยังใช้แลมบ์ดาเมื่อทำงานกับสตรีม (ดังในตัวอย่างที่มีสตรีมด้านบน) เราจะไม่ลงลึกเกินไป เนื่องจากเราสามารถดำน้ำได้ค่อนข้างลึก ฉันจะทิ้งลิงก์ไว้สองสามลิงก์เพื่อให้คนที่ยังเป็นนักขุดในใจสามารถเจาะลึกได้:
- บทความเกี่ยวกับนิพจน์แลมบ์ดาใน Java 8 บนHabré
- บทความเกี่ยวกับนิพจน์แลมบ์ดาใน Javaบนบล็อกของ Alexander Kosarev
แต่ละ
Java 8 มี foreach ใหม่ที่ทำงานร่วมกับสตรีมข้อมูลเช่นเดียวกับสตรีม นี่คือตัวอย่าง:List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);
someList.forEach(x -> System.out.println(x));
(คล้ายกับ someList.stream().foreach(…))
การอ้างอิงวิธีการ
วิธีการอ้างอิงเป็นไวยากรณ์ใหม่ที่มีประโยชน์ซึ่งออกแบบมาเพื่ออ้างอิงวิธีการที่มีอยู่หรือตัวสร้างคลาสหรืออ็อบเจ็กต์ Java ผ่านทาง :: การอ้างอิงวิธีการมีสี่ประเภท:-
ลิงค์ไปยังนักออกแบบ:
SomeObject obj = SomeObject::new
-
การอ้างอิงวิธีการคงที่:
SomeObject::someStaticMethod
-
การอ้างอิงถึงวิธีการไม่คงที่ของวัตถุบางประเภท:
SomeObject::someMethod
-
การอ้างอิงถึงวิธีการปกติ (ไม่คงที่) ของวัตถุเฉพาะ
obj::someMethod
someList.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
สำหรับผู้ที่ต้องการข้อมูลเพิ่มเติมเกี่ยวกับวิธีการอ้างอิง:
เวลาเอพีไอ
มีไลบรารีใหม่สำหรับการทำงานกับวันที่และเวลา - java.time
- LocalDateคือวันที่ที่ระบุ ดังตัวอย่าง - 2010-01-09
- LocalTime - เวลาที่คำนึงถึงเขตเวลา - 19:45:55 (คล้ายกับ LocalDate)
- LocalDateTime - คอมโบ LocalDate + LocalTime - 2020-01-04 15:37:47;
- ZoneId - หมายถึงโซนเวลา
- นาฬิกา - เมื่อใช้ประเภทนี้ คุณจะสามารถเข้าถึงเวลาและวันที่ปัจจุบันได้
- Java และเวลา: ตอนที่หนึ่งและสองเกี่ยวกับHabré
- รู้เบื้องต้นเกี่ยวกับ Date/Time API ใน Java 8
ไม่จำเป็น
นี่เป็นคลาสใหม่ใน แพ็คเกจ java.utilซึ่งเป็นตัวห่อค่าที่มีเคล็ดลับคือสามารถมีnull ได้อย่าง ปลอดภัย การรับทางเลือก: ถ้า เราผ่านnullOptional<String> someOptional = Optional.of("Something");
ในOptional.ofเราจะได้รับNullPointerException ที่ เรา ชื่นชอบ ในกรณีเช่นนี้ พวกเขาใช้: - ในวิธีนี้ คุณไม่จำเป็นต้องกลัวว่าจะว่างเปล่า ถัดไป สร้างช่องว่างในตอนแรก ตัวเลือก: หากต้องการตรวจสอบว่าว่างเปล่าหรือไม่ ให้ใช้: จะส่งคืนค่าจริงหรือเท็จให้เรา ดำเนินการบางอย่างหากมีค่าและไม่ทำอะไรเลยหากไม่มีค่า: วิธีการย้อนกลับที่ส่งคืนค่าที่ส่งหาก Optional ว่างเปล่า (ประเภทของแผนสำรอง): คุณสามารถดำเนินการต่อได้เป็นเวลานานมาก ( โชคดีที่ทางเลือกได้เพิ่มวิธีการด้วยมือที่ใจกว้างทั้งสอง) แต่เราจะไม่ยึดติดกับเรื่องนี้ เป็นการดีกว่าสำหรับฉันที่จะทิ้งลิงก์ไว้สองสามลิงก์สำหรับผู้เริ่มต้น: Optional<String> someOptional = Optional.ofNullable("Something");
Optional<String> someOptional = Optional.empty();
someOptional.isPresent();
someOptional.ifPresent(System.out::println);
System.out.println(someOptional.orElse("Some default content"));
- Java Optional - บิดาแห่งโฮลิวาร์
- ทางเลือก: แมวของSchrödingerใน Java 8
- คลาสเสริมใหม่ใน Java 8 ไม่ใช่ยาครอบจักรวาลสำหรับ NullPointerException
- คุณสมบัติของ Java 8: สุดยอดคู่มือ JavaRush - ตอนที่หนึ่งและสอง ;
- ใหม่ใน Java 8 บนHabré ;
- คุณสมบัติ 10 อันดับแรกของ Java 8 ที่ผู้คนไม่ได้พูดถึง ;
- บทช่วยสอน Java 8
จาวา 9
ดังนั้นในวันที่ 21 กันยายน 2017 โลกได้เห็น JDK 9 Java 9 นี้มาพร้อมกับชุดคุณสมบัติที่หลากหลาย แม้ว่าจะไม่มีแนวคิดด้านภาษาใหม่ แต่ API และคำสั่งการวินิจฉัยใหม่จะเป็นที่สนใจของนักพัฒนาอย่างแน่นอน
JShell (REPL - ลูป read-eval-print)
นี่คือการใช้งาน Java ของคอนโซลเชิงโต้ตอบที่ใช้เพื่อทดสอบการทำงานและใช้โครงสร้างที่แตกต่างกันในคอนโซล เช่น อินเทอร์เฟซ คลาส การแจงนับ ตัวดำเนินการ ฯลฯ หากต้องการเปิดJShellคุณเพียงแค่ต้องเขียน jshell ลงในเทอร์มินัล จากนั้นเราสามารถเขียนอะไรก็ได้ตามจินตนาการของเรา:
ส่วนตัว
เริ่มต้นด้วย Java เวอร์ชัน 9 เรามีโอกาสที่จะใช้วิธีการส่วนตัวในอินเทอร์เฟซ (วิธีการเริ่มต้นและแบบคงที่ เนื่องจากเราไม่สามารถแทนที่วิธีอื่นได้เนื่องจากการเข้าถึงไม่เพียงพอ)private static void someMethod(){}
try-with-resources
ความสามารถในการจัดการข้อยกเว้น Try-With-Resources ได้รับการอัปเกรดแล้ว:
BufferedReader reader = new BufferedReader(new FileReader("....."));
try (reader2) {
....
}
โมดูลาร์ ( จิ๊กซอว์ )
โมดูลคือกลุ่มของแพ็กเกจและรีซอร์สที่เกี่ยวข้องพร้อมกับไฟล์อธิบายโมดูลใหม่ วิธีการนี้ใช้เพื่อคลายการเชื่อมต่อของโค้ด การมีเพศสัมพันธ์แบบหลวมเป็นปัจจัยสำคัญสำหรับการบำรุงรักษาและการขยายรหัส ความเป็นโมดูลถูกนำไปใช้ในระดับต่างๆ:- ภาษาโปรแกรม
- เครื่องเสมือน
- จาวา API มาตรฐาน
คอลเลกชันที่ไม่เปลี่ยนรูป
ใน Java 9 มันเป็นไปได้ที่จะสร้างและเติมคอลเลกชันด้วยบรรทัดเดียว ในขณะที่ทำให้มันไม่เปลี่ยนรูป (ก่อนหน้านี้ ในการสร้างคอลเลกชันที่ไม่เปลี่ยนรูป เราจำเป็นต้องสร้างคอลเลกชัน กรอกข้อมูลด้วยข้อมูล และเรียกใช้เมธอด เช่น Collections.unmodifiableList) ตัวอย่างของการสร้างสรรค์ดังกล่าว:List someList = List.of("first","second","third");
นวัตกรรมอื่นๆ:
- ขยายทางเลือก (เพิ่มวิธีการใหม่);
- อินเทอร์เฟซ ProcessHandle และ ProcessHandle ดูเหมือนจะควบคุมการทำงานของระบบปฏิบัติการ
- G1 - ตัวรวบรวมขยะเริ่มต้น
- ไคลเอ็นต์ HTTP ที่รองรับทั้งโปรโตคอล HTTP/2 และ WebSocket
- กระแสขยาย;
- เพิ่มเฟรมเวิร์ก Reactive Streams API (สำหรับการเขียนโปรแกรมเชิงโต้ตอบ);
- รีวิว Java 9บนHabré
- จาวา 9 มีอะไรใหม่?
- Java 9: คุณสมบัติใหม่
- Java 9 - คุณได้อัปเกรดแล้วหรือยัง? เลขที่? และไม่จำเป็น ...!?
- Sander Mak เกี่ยวกับการเปลี่ยนไปใช้โมดูล Java
จาวา 10
ดังนั้น หกเดือนหลังจากการเปิดตัว Java 9 ในเดือนมีนาคม 2018 (ฉันจำได้เหมือนเมื่อวาน) Java 10 ก็เข้ามามีบทบาท
var
ตอนนี้เราไม่จำเป็นต้องระบุประเภทข้อมูล เราทำเครื่องหมายข้อความเป็น var และคอมไพลเลอร์จะกำหนดประเภทของข้อความตามประเภทของตัวเริ่มต้นที่อยู่ทางด้านขวา คุณลักษณะนี้ใช้ได้เฉพาะกับตัวแปรโลคัลที่มีตัวเริ่มต้นเท่านั้น โดยไม่สามารถใช้กับอาร์กิวเมนต์ของเมธอด ประเภทการส่งคืน ฯลฯ เนื่องจากไม่มีตัวเริ่มต้นที่จะสามารถกำหนดประเภทได้ ตัวอย่าง var (สำหรับประเภท String):var message = "Some message…..";
System.out.println(message);
var ไม่ใช่คีย์เวิร์ด: โดยพื้นฐานแล้วมันคือชื่อประเภทที่สงวนไว้ เช่นเดียวกับint ประโยชน์ของvarนั้นดีมาก: การประกาศประเภทดึงความสนใจอย่างมากโดยไม่เกิดประโยชน์ใดๆ และฟีเจอร์นี้จะช่วยประหยัดเวลา แต่ในขณะเดียวกัน หากได้รับตัวแปรจากวิธีการที่หลากหลาย โค้ดก็จะอ่านได้น้อยลง เนื่องจากไม่ชัดเจนในทันทีว่ามีวัตถุประเภทใดอยู่ที่นั่น ทุ่มเทให้กับผู้ที่ต้องการทำความคุ้นเคยกับฟังก์ชันนี้มากขึ้น:
- Java 10 LocalVariable Type-Inference
- การติดต่อครั้งแรกกับ "var" ใน Java 10
- 26 เคล็ดลับในการใช้ var Type ใน Java
คอมไพเลอร์ JIT (GraalVM)
เพื่อเป็นการไม่ให้เสียเวลา ฉันขอเตือนคุณว่าเมื่อคุณรันคำสั่ง javac แอปพลิเคชัน Java จะถูกคอมไพล์จากโค้ด Java เป็นโค้ดไบต์ JVM ซึ่งเป็นการแสดงไบนารีของแอปพลิเคชัน แต่โปรเซสเซอร์คอมพิวเตอร์ทั่วไปไม่สามารถรันโค้ดไบต์ JVM ได้ง่ายๆ เพื่อให้โปรแกรม JVM ของคุณทำงานได้ คุณต้องมีคอมไพเลอร์อื่นสำหรับโค้ดไบต์นี้ ซึ่งจะถูกแปลงเป็นรหัสเครื่องที่โปรเซสเซอร์สามารถใช้ได้อยู่แล้ว เมื่อเปรียบเทียบกับ javac คอมไพเลอร์นี้ซับซ้อนกว่ามาก แต่ยังสร้างโค้ดเครื่องคุณภาพสูงกว่าอีกด้วย ปัจจุบันOpenJDKมีเครื่องเสมือน HotSpot ซึ่งมีคอมไพเลอร์ JIT หลักสองตัว อันแรก C1 ( ไคลเอนต์คอมไพเลอร์ ) ได้รับการออกแบบมาเพื่อการทำงานที่ความเร็วสูงกว่า แต่การปรับโค้ดให้เหมาะสมก็ประสบปัญหา อย่างที่สองคือ C2 (คอมไพเลอร์เซิร์ฟเวอร์) ความเร็วในการดำเนินการลดลง แต่โค้ดได้รับการปรับปรุงให้เหมาะสมยิ่งขึ้น อันไหนใช้เมื่อไร? C1 นั้นยอดเยี่ยมสำหรับแอปพลิเคชันบนเดสก์ท็อปที่การหยุด JIT เป็นเวลานานเป็นสิ่งที่ไม่พึงประสงค์ และ C2 นั้นยอดเยี่ยมสำหรับโปรแกรมเซิร์ฟเวอร์ที่รันระยะยาวซึ่งการใช้เวลาในการคอมไพล์มากขึ้นนั้นค่อนข้างจะทนได้ การคอมไพล์หลายระดับคือการคอมไพล์ครั้งแรกผ่าน C1 และผลลัพธ์ผ่าน C2 (ใช้สำหรับการปรับให้เหมาะสมยิ่งขึ้น) GraalVMเป็นโครงการที่สร้างขึ้นเพื่อแทนที่ HotSpot โดยสมบูรณ์ เรามอง Graal ว่าเป็นโปรเจ็กต์ที่เกี่ยวข้องกันหลายโปรเจ็กต์: คอมไพเลอร์ JIT ใหม่สำหรับ HotSpot และเครื่องเสมือนพูดได้หลายภาษาใหม่ ลักษณะเฉพาะของคอมไพเลอร์ JIT นี้คือเขียนด้วยภาษา Java ข้อดีของคอมไพเลอร์ Graal คือความปลอดภัย นั่นคือ ไม่ล่ม แต่เป็นข้อยกเว้น ไม่ใช่หน่วยความจำรั่ว นอกจากนี้เรายังได้รับการสนับสนุน IDE ที่ดีและเราจะสามารถใช้ดีบักเกอร์ ผู้สร้างโปรไฟล์ หรือเครื่องมืออำนวยความสะดวกอื่น ๆ ได้ นอกจากนี้ คอมไพลเลอร์อาจไม่ขึ้นอยู่กับ HotSpot และจะสามารถสร้างเวอร์ชันที่คอมไพล์ด้วย JIT ของตัวเองได้เร็วขึ้น สำหรับผู้ขุด:- เจาะลึก Java JIT Compiler ใหม่
- Graal: วิธีใช้คอมไพเลอร์ JVM JIT ใหม่ในชีวิตจริง
- Graal ทำงานอย่างไร - คอมไพเลอร์ Java JVM JIT
ขนาน G1
ตัวรวบรวมขยะ G1 นั้นเจ๋งอย่างแน่นอนไม่ต้องสงสัยเลย แต่ก็มีจุดอ่อนเช่นกัน: มันดำเนินการวงจร GC แบบเต็มเธรดเดียว ในช่วงเวลาที่คุณต้องการพลังทั้งหมดของฮาร์ดแวร์ที่สามารถรวบรวมเพื่อค้นหาวัตถุที่ไม่ได้ใช้ เราถูกจำกัดไว้เพียงเธรดเดียว Java 10 แก้ไขปัญหานี้แล้ว ตอนนี้ GC ทำงานร่วมกับทรัพยากรทั้งหมดที่เราเพิ่มเข้าไปแล้ว (นั่นคือ กลายเป็นแบบมัลติเธรด) เพื่อให้บรรลุเป้าหมายนี้ นักพัฒนาภาษาได้ปรับปรุงการแยกแหล่งข้อมูลหลักออกจาก GC เพื่อสร้างอินเทอร์เฟซที่สวยงามสำหรับ GC นักพัฒนา OpenJDK ที่น่ารักนี้ต้องล้างดัมพ์ในโค้ดโดยเฉพาะ ไม่เพียงแต่ทำให้การสร้าง GC ใหม่ง่ายขึ้นมากที่สุดเท่าที่จะเป็นไปได้ แต่ยังทำให้สามารถปิดการใช้งาน GC ที่ไม่จำเป็นจากแอสเซมบลีได้อย่างรวดเร็วอีกด้วย หนึ่งในเกณฑ์หลักสู่ความสำเร็จคือการไม่มีการลดความเร็วในการทำงานหลังจากการปรับปรุงทั้งหมดนี้ ลองดูด้วย: นวัตกรรมอื่นๆ:- มีการแนะนำอินเทอร์เฟซ Garbage-Collector ที่สะอาด สิ่งนี้จะช่วยปรับปรุงการแยกซอร์สโค้ดจากตัวรวบรวมขยะต่างๆ ทำให้สามารถรวมตัวรวบรวมทางเลือกอื่นได้อย่างรวดเร็วและไม่ลำบาก
- การรวมแหล่ง JDK ไว้ในที่เก็บข้อมูลเดียว
- คอลเลกชันได้รับวิธีการใหม่ - copyOf (Collection)ซึ่งส่งคืนสำเนาที่ไม่เปลี่ยนรูปแบบของคอลเลกชันนี้
- ตัวเลือก (และตัวแปร) มีวิธีการใหม่.orElseThrow() ;
- จากนี้ไป JVM ทราบว่าพวกเขากำลังทำงานในคอนเทนเนอร์ Docker และจะดึงข้อมูลการกำหนดค่าเฉพาะคอนเทนเนอร์แทนที่จะสอบถามระบบปฏิบัติการเอง
- คำแนะนำเกี่ยวกับ Java 10
- 10 คุณสมบัติ JDK 10 ที่นักพัฒนา Java ควรรู้
- มีอะไรใหม่ใน Java 10: ส่วนที่หนึ่งและสอง
GO TO FULL VERSION