תכונות חדשות של Java 9

1. סקירה כללית

Java 9 מגיע עם ערכת תכונות עשירה. למרות שאין מושגי שפה חדשים, ממשקי API חדשים ופקודות אבחון בהחלט יהיו מעניינים למפתחים.

במחקר זה אנו נסתכל על כמה מהתכונות החדשות ברמה גבוהה ומהירה; רשימה מלאה של תכונות חדשות זמינה כאן.

2. מערכת מודולרית - פרויקט פאזל

נתחיל בגדול - הכנסת מודולריות לפלטפורמת Java.

מערכת מודולרית מספקת יכולות הדומות למערכת OSGi framework. למודולים מושג של תלות, ניתן לייצא ממשק API ציבורי ולשמור את פרטי היישום מוסתרים / פרטיים.

אחד המניעים העיקריים כאן הוא לספק JVM מודולרי, שיכול לפעול במכשירים עם הרבה פחות זיכרון זמין. ה- JVM יכול לפעול רק עם אותם מודולים ו- API שדורשים היישום. עיין בקישור זה לתיאור מה הם המודולים האלה.

כמו כן, ממשקי API פנימיים (יישום) של JVM כמו com.sun. * כבר אינם נגישים מקוד היישום.

במילים פשוטות, המודולים מתוארים בקובץ שנקרא module-info.java ממוקם בראש ההיררכיה של קוד java:

מודול com.baeldung.java9.modules.car {דורש com.baeldung.java9.modules.engines; יצוא com.baeldung.java9.modules.car.handling; } 

המודול שלנו אוטו דורש מודול מנוע להריץ ולייצא חבילה עבור טיפול.

לקבלת דוגמה מעמיקה יותר, בדוק את OpenJDK Project Jigsaw: מדריך ההפעלה המהיר של מערכת המערכת.

3. לקוח HTTP חדש

תחליף המיוחל של הישן חיבור HttpURLC.

ה- API החדש נמצא תחת ה- java.net.http חֲבִילָה.

הוא אמור לתמוך גם בפרוטוקול HTTP / 2 וגם בלחיצת יד של WebSocket, עם ביצועים שאמורים להיות דומים ל- Apache HttpClient, Netty ו- Jetty.

בואו נסתכל על הפונקציונליות החדשה הזו על ידי יצירה ושליחה של בקשת HTTP פשוטה.

עדכון: JEP לקוח ה- HTTP מועבר למודול החממה, כך שהוא כבר לא זמין בחבילה java.net.http ובמקום זה זמין תחת jdk.incubator.http.

3.1. בקשת GET מהירה

ה- API משתמש בתבנית Builder, מה שמאוד קל לשימוש מהיר:

HttpRequest בקשה = HttpRequest.newBuilder () .uri (URI חדש ("// postman-echo.com/get")). GET () .build (); תגובה HttpResponse = HttpClient.newHttpClient (). לשלוח (בקשה, HttpResponse.BodyHandler.asString ()); 

4. ממשק API לתהליך

ממשק ה- API של התהליך שופר לבקרה וניהול של תהליכי מערכת הפעלה.

4.1. מידע על התהליך

הכיתה java.lang.ProcessHandle מכיל את רוב הפונקציות החדשות:

ProcessHandle עצמי = ProcessHandle.current (); PID ארוך = self.getPid (); ProcessHandle.Info procInfo = self.info (); ארגונים אופציונליים = procInfo.arguments (); Cmd אופציונלי = procInfo.commandLine (); StartTime אופציונלי = procInfo.startInstant (); CpuUsage אופציונלי = procInfo.totalCpuDuration ();

ה נוֹכְחִי השיטה מחזירה אובייקט המייצג תהליך של הפעלת JVM כרגע. ה מידע תת מחלקה מספקת פרטים על התהליך.

4.2. תהליכי הרס

עכשיו - בואו נעצור את כל התהליכים של הילד המפעיל להרוס():

childProc = ProcessHandle.current (). ילדים (); childProc.forEach (procHandle -> {assertTrue ("לא ניתן היה להרוג את התהליך" + procHandle.getPid (), procHandle.destroy ());});

5. שינויים בשפה קטנה

5.1. נסה עם משאבים

ב- Java 7, ה- נסה עם משאבים תחביר מחייב להכריז על משתנה חדש עבור כל משאב המנוהל על ידי הצהרה.

בג'אווה 9 יש חידוד נוסף: אם המשאב מוזכר על ידי משתנה סופי או יעיל, משפט משפט עם משאבים יכול לנהל משאב בלי שמשתנה חדש יוכרז:

MyAutoCloseable mac = MyAutoCloseable חדש (); נסה (mac) {// עשה דברים עם mac} נסה (MyAutoCloseable חדש () {} .finalWrapper.finalCloseable) {// עשה כמה דברים עם לתפוס finalCloseable} (למשל חריג) {} 

5.2. הרחבת מפעילי יהלומים

כעת אנו יכולים להשתמש במפעיל יהלומים בשילוב עם מעמדות פנימיים אנונימיים:

FooClass fc = FooClass חדש (1) {// מחלקה פנימית אנונימית}; FooClass fc0 = FooClass חדש (1) {// מחלקה פנימית אנונימית}; FooClass fc1 = FooClass חדש (1) {// מחלקה פנימית אנונימית}; 

5.3. ממשק פרטי שיטה

ממשקים בגרסת JVM הקרובה יכולים להיות פְּרָטִי שיטות, בהן ניתן לפצל שיטות ברירת מחדל ארוכות:

ממשק InterfaceWithPrivateMethods {פרטי סטטי מחרוזת staticPrivate () {להחזיר "סטטי פרטי"; } מופע פרטי מחרוזת פרטי () {להחזיר "מופע פרטי"; } ברירת מחדל של בטל ריק () {מחרוזת תוצאה = staticPrivate (); InterfaceWithPrivateMethods pvt = InterfaceWithPrivateMethods חדש () {// מחלקה אנונימית}; תוצאה = pvt.instancePrivate (); }}}

6. כלי שורת הפקודה JShell

JShell הוא קריאה – הערכה –לולאת הדפסה - בקיצור REPL.

במילים פשוטות, זהו כלי אינטראקטיבי להערכת הצהרות, הצהרות וביטויים של Java, יחד עם API. זה מאוד נוח לבדיקת קטעי קוד קטנים, שאחרת דורשים ליצור מחלקה חדשה עם ה- רָאשִׁי שיטה.

ה jshell את ההפעלה עצמה ניתן למצוא ב /פַּח תיקיה:

jdk-9 \ bin> jshell.exe | ברוכים הבאים ל- JShell - גרסה 9 | לסוג מבוא: / help intro jshell> "זו המחרוזת הארוכה שלי. אני רוצה חלק ממנה". Substring (8,19); $ 5 ==> "המחרוזת הארוכה שלי"

המעטפת האינטראקטיבית מגיעה עם היסטוריה והשלמה אוטומטית; זה גם מספק פונקציונליות כמו שמירה וטעינה מקבצים, כל ההצהרות הכתובות או חלק מהן:

jshell> / save c: \ develop \ JShell_hello_world.txt jshell> / open c: \ develop \ JShell_hello_world.txt שלום JShell! 

קטעי קוד מבוצעים עם טעינת הקובץ.

7. פקודות משנה של JCMD

בואו לחקור כמה מתתי הפקודות החדשות ב jcmd כלי שורת הפקודה. נקבל רשימה של כל הכיתות הטעונות ב- JVM ומבנה הירושה שלהן.

בדוגמה שלמטה אנו יכולים לראות את ההיררכיה של java.lang. שקע נטען ב- JVM הפועל ניאון ליקוי חמה:

jdk-9 \ bin> jcmd 14056 VM.class_hierarchy -i -s java.net.Socket 14056: java.lang.Object / null | --java.net.Socket / null | מיישמת java.io.Closeable / null (הצהרת intf) | מיישם java.lang.AutoCloseable / null (intf בירושה) | | --org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket | | מיישם java.lang.AutoCloseable / null (intf בירושה) | | מיישם java.io.Closeable / null (בירושה intf) | | --javax.net.ssl.SSLSocket / null | | מיישם java.lang.AutoCloseable / null (intf בירושה) | | מיישם java.io.Closeable / null (intf בירושה) 

הפרמטר הראשון של jcmd פקודה היא מזהה התהליך (PID) של ה- JVM עליו אנו רוצים להפעיל את הפקודה.

פקודת משנה מעניינת נוספת היא set_vmflag. אנו יכולים לשנות כמה פרמטרים של JVM באופן מקוון, ללא צורך להפעיל מחדש את תהליך JVM ולשנות את פרמטרי ההפעלה שלו.

אתה יכול לגלות את כל דגלי ה- VM הזמינים באמצעות תת-פקודה jcmd 14056 VM.flags -all

8. ממשק API מרובי רזולוציה תמונה

הממשק java.awt.image.MultiResolutionImage מכיל סט של תמונות ברזולוציות שונות לאובייקט יחיד. אנו יכולים לאחזר גרסת תמונה ספציפית לרזולוציה המבוססת על מדד DPI נתון וקבוצת תמורות תמונה או לאחזר את כל הגרסאות בתמונה.

ה java.awt. גרפיקה בכיתה מקבל גרסה מתמונה ברזולוציה מרובה המבוססת על מדד התצוגה הנוכחי של DPI ועל כל שינוי שעבר.

הכיתה java.awt.image.BaseMultiResolutionImage מספק יישום בסיסי:

BufferedImage [] resolutionVariants = .... MultiResolutionImage bmrImage = BaseMultiResolutionImage חדש (baseIndex, resolutionVariants); תמונה testRVImage = bmrImage.getResolutionVariant (16, 16); assertSame ("התמונות צריכות להיות זהות", testRVImage, resolutionVariants [3]); 

9. ידיות משתנות

ה- API נמצא תחת java.lang.inoke ומורכב מ VarHandle ו שיטה ידיות. זה מספק שווי ערך של java.util.concurrent.atomic ו sun.misc. לא בטוח פעולות על שדות אובייקט ומרכיבי אלמנטים עם ביצועים דומים.

עם ג 'אווה 9 מערכת מערכת מודולרית אל sun.misc. לא בטוח לא יהיה אפשרי מקוד היישום.

10. פרסום-הרשמה למסגרת

הכיתה java.util.concurrent.Flow מספק ממשקים התומכים במסגרת Reactive Streams כמנויים לפרסום. ממשקים אלה תומכים ביכולת פעולה הדדית במספר מערכות אסינכרוניות הפועלות על JVM.

אנחנו יכולים להשתמש בכיתת שירות הגשה מפרסם כדי ליצור רכיבים מותאמים אישית.

11. רישום JVM מאוחד

תכונה זו מציגה מערכת רישום נפוצה לכל מרכיבי ה- JVM. הוא מספק את התשתית לביצוע הרישום, אך אינו מוסיף את שיחות הרישום בפועל מכל רכיבי JVM. זה גם לא מוסיף כניסה לקוד Java ב- JDK.

מסגרת הרישום מגדירה קבוצה של תגים - לדוגמה, gc, מַהְדֵר, חוטיםוכו 'אנו יכולים להשתמש בפרמטר שורת הפקודה -Xlog להפעיל רישום במהלך ההפעלה.

בואו נרשום הודעות שתויגו בתג 'gc' באמצעות רמת 'ניפוי באגים' לקובץ בשם 'gc.txt' ללא קישוטים:

java -Xlog: gc = debug: file = gc.txt: none ...

-Xlog: עזרה יפיק אפשרויות ודוגמאות אפשריות. ניתן לשנות את תצורת הרישום באמצעות jcmd פקודה. אנחנו הולכים להגדיר יומני GC למידע ולהפנות אותם לקובץ - gc_logs:

jcmd 9615 VM.log פלט = gc_logs מה = gc

12. ממשקי API חדשים

12.1. סט בלתי משתנה

java.util.Set.of () - יוצר סט בלתי משתנה של אלמנטים נתונים. ב- Java 8 יצירת סט של כמה אלמנטים תדרוש מספר שורות קוד. עכשיו אנחנו יכולים לעשות את זה פשוט כמו:

הגדר strKeySet = Set.of ("key1", "key2", "key3");

ה מַעֲרֶכֶת המוחזר בשיטה זו הוא מחלקה פנימית של JVM: java.util.ImmutableCollections.SetN, המרחיב את הציבור java.util.AbstractSet. אי אפשר לשנות את זה - אם ננסה להוסיף או להסיר אלמנטים, לא נתמךOperationException ייזרק.

ניתן גם להמיר מערך שלם ל- מַעֲרֶכֶת באותה שיטה.

12.2. אופציונלי לזרם

java.util.Optional.stream () נותן לנו דרך קלה להשתמש בכוחם של זרמים על אלמנטים אופציונליים:

רשימה filteredList = listOfOptionals.stream () .flatMap (אופציונלי :: stream) .collect (Collectors.toList ()); 

13. מסקנה

Java 9 יגיע עם JVM מודולרי ועוד המון שיפורים ותכונות חדשים ומגוונים.

אתה יכול למצוא את קוד המקור עבור הדוגמאות ב- GitHub.