Java 10 הוא השחרור המהיר ביותר של גרסת Java בהיסטורייתה של 23 שנים. ייתכן ש- Java קיבלה ביקורת על צמיחתה ותפוצתה האיטית, אך Java 10 פשוט פיצצה את העצות הללו. Java 10 היא גרסה עם שינויים רבים ועתידניים, תחום והשפעתם שלהם יכולים לא להיראות ברורים, אך הם מתקדמים. במאמר זה, נדון בקשר לתכונות השונות שנוספו בשחרור Java10. לפני כן, נביט על מספר השינויים שהוכנסו לדגם שחרור של Java.
דגם תמיכה לטווח ארוך
מתחילת שנת 2017, אורקל וקהילת Java הכריזו על המעבר שלהם לקדנציה חדשה בת 6 חודשים עבור Java. הם העבירו לדגם של תמיכה לטווח ארוך (LTS) עבור מוצרי Oracle Java SE. מה זה אומר? גרסת ה-LTS של המוצרים תציע תמיכה מובילה ומתמידה מ-Oraclו והיא תכוון לכל 3 שנים. כל גרסת Java מודלפת לפי תכונת משמעות ראשית או שתיים, תכונות אלו מניעות את השחרור. כל מכשול מאחר את השחרור ומאחר בהשקה לשוק. פרויקט Jigsaw היה תכונה משמעותית ב-Java 9, הוא דחה את תאריכי השחרור כמה פעמים והשחרור הוחזק ביותר משנה וחצי. גרסת הקדנציה של 6 חודשים תמשיך לעקוב אחר רכבת השחרורים. רכבת השחרורים תכיל לוח זמנים לכל 6 חודשים. תכונות שעוברות את החתימה נכנסות לרכבת; אחרת הן ממתינות לרכבת הבאה המתוזמנת.
Oracle JDK נגד Open JDK
כדי להיות ידידותי יותר למפתחים, אספקת ה-JDK הראשית כעת מקדמת את הקבצים של OpenJDK כ-JDK הראשי העתידי. זהו פתרון גדול מימיו הקודמים, כאשר קבצי ה-JDK היו פטנטים ורשומים על ידי Oracle, שהיו להם הרבה הגבלות סביב הפצה מחדש. אורקל, עם זאת, תמשיך לייצר את ה-JDK שלה, אך רק עבור גרסאות תמיכה לטווח ארוך. זהו צעד להיות יותר ידידותיים לענן ולקונטיינרים, מאחר שקבצי ה-JDK הפתוחים יכולים להיות מופצים כחלק מקונטיינר. מה זה אומר? קבצי ה-JDK של Open JDK יישארו מוצגים כל 6 חודשים, בעוד קבצי ה-JDK של Oracle יישארו מוצגים כל 3 שנים (גרסת LTS). אילו קבצי JDK יתקבלו? ארגונים גדולים דורשים זמן כדי לעבור בין הגרסאות; הם מתמכרים לגרסה עד שיוכלו. המימוש התעשייתי של Java 6 היה יותר רחב מאשר Java 7 ואז התעשייה מעברה בהדרגה אל Java 8. בעיניי, הגרסה של LTS תהיה הפופולרית ביותר על ידי העסקים. אך, האם זה יהיה הגרסה של LTS של Oracle JDK או של Open JDK עוד לא ידוע, לפחות בחלק משום שיש הרבה דברים שקורים בתחום הענן. Java 9 ו-10 הם גרסאות שאינן LTS. Java 11 שמתוכננת לספטמבר 2018 תהיה גרסת LTS.
תכונות Java 10
בואו נשקף מהר על התכונות הזמינות ב-Java 10.
עם אימוץ מחזור השחרורים המבוסס על זמן, Oracle שינתה את תפריט גרסאות מדגם סדרת ה-Java SE וה-JDK, ומידע קשור לגירסאות, למודלי שחרור מבוססי זמן נוכחיים ועתידיים. התבנית החדשה של מספר הגירסה היא: $FEATURE.$INTERIM.$UPDATE.$PATCH
$FEATURE: מונה יתגבר כל 6 חודשים ויתבסס על גרסאות שחרור תכונות, לדוגמה: JDK 10, JDK 11.
$INTERIM: מונה יתגבר לגרסאות שחרור לא תכונתיות המכילות תיקוני באגים תואמים ושיפורים אך לא שינויים לא תואמים. בדרך כלל, זה יהיה אפס, מאחר ולא יהיה שחרור זמני בתקופת שישה חודשים. זה נשמר לתיקון עתידי של המודל שחרור.
$UPDATE: מונה יתגבר לשחרורי עדכון תואמים התוקנים בעיות אבטחה, חזרות ובאגים בתכונות חדשות. זה מתעדכן חודש אחרי שחרור התכונה וכל 3 חודשים לאחר מכן. שחרור אפריל 2018 הוא JDK 10.0.1, השחרור ביולי הוא JDK 10.0.2, וכן הלאה.
$PATCH: מונה יתגבר לשחרור חירום לתיקון בעיה קריטית. נוספו API חדשות לקבלת ערכי המונים אלו באופן תכנותי. בואו נסתכל;
Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();
עכשיו, בואו נביט באפשרות לכוכב Java שמחזיר מידע על הגירסה:
$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
תבנית מספר הגירסה היא "10" מאחר שאין מונה אחר שאינו אפס. התאריך של השחרור מתווסף. 18.3 ניתן לקרוא כשנת 2018 וחודש השלישי, בניית 10+46 היא בניית ה-46 לגירסה 10. לבניית היפותטית 93 של JDK 10.0.1, הבנייה תהיה 10.0.1+939. ### Local-Variable Type Inference (JEP 286)
הסמכת סוג משתנה מקומי היא התכונה החדשה ביותר ב-Java 10 עבור מפתחים. זה מוסיף סמכת סוג להצהרות של משתנים מקומיים עם מאתחלים. הסמכת סוג מקומית ניתן להשתמש בה רק בתרחישים הבאים:
- מוגבל רק למשתנה מקומי עם מאתחל
- מספרי מערך של לולאת for משודרגת או מספרים
- מקומי מצוין בלולאת for
בואו נסתכל על השימוש שלו:
var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList
// אינדקס של לולאת For משודרגת
for (var number : numbers) {
System.out.println(number);
}
// משתנה מקומי מוגדר בלולאה
for (var i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
ניתן לקרוא עוד על זה בפוסט הבלעדי שלנו על סמכת סוג של משתנה מקומי ב-Java 10. 13. ### מהדורת JIT של Java המבוססת על ניסיונית (JEP 317)
תכונה זו מאפשרת למהדר JIT המבוסס על Java, Graal, לשמש כמהדר JIT ניסיוני על פלטפורמת Linux/x64. זהו ללא ספק הכלול המותירני ביותר ברשימת התכונות של Java 10. Graal נכנסה לשימוש ב-Java 9. זו אלטרנטיבה למהדר JIT שהיינו רגילים אליו. היא היא תוסף ל-JVM, כלומר המהדר JIT אינו מקושר ל-JVM וניתן לחברו באופן דינמי ולהחליף אותו בתוסף אחר התואם ל- JVMCI (ממשק מהדר JVM ברמת Java). היא גם מביאה קידום קוד מראש (AOT) לעולם Java. היא תומכת גם בפרשנות של שפות פוליגלוטיות. "מהדר JIT מבוסס על Java מוגדר ב-Java כדי להמיר את קוד ה- bytecode של Java לקוד מכונה." האם זה מבלבל? אם JVM נכתבת ב-Java, אז האם אתה לא צריך JVM כדי להפעיל את ה-JVM? ה-JVM יכולה להידרדר AOT ואז ניתן להשתמש במהדר JIT בתוך ה-JVM כדי לשפר את הביצועים דרך אופטימיזציה של קוד חי. Graal היא כתיבה מחדש מוחלטת של המהדר JIT ב-Java מאפס. המהדר JIT הקודם כתבו ב-c++. הוא נחשב לשלב הסופי ביותר של התפתחות עבור שפת תכנות כלשהי. אתה יכול להחליף ל-Graal עם הפרמטרים הבאים של JVM:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
ניתן ללמוד עוד על Graal מההצגה של Chris Seaton.
התכונה הזו עוזרת לשפר את העקבות הראשונית של האפליקציה, הולכת על פרק על מה שנקרא "שיתוף נתוני קבוצת-כיתה" ("CDS") כדי לאפשר למחלקות של האפליקציה להיות ממוקמות בארכיון משותף. הJVM, בעת התחלתה, מבצעת כמה שלבים מוקדמים, כאחד מהם הוא טעינת מחלקות לזיכרון. אם ישנם מספר רב של JARs עם מספר רב של מחלקות, אז השגיאה בבקשה הראשונה גלויה באופן ברור. זה יכול להיות בעיה עם ארכיטקטורת ה-Serverless, שבה זמן הטעינה קריטי. כדי להפחית את זמן התחלת האפליקציה, ניתן להשתמש בשיתוף נתוני קבוצת-כיתה של האפליקציה. הרעיון הוא להפחית את העקבות על ידי שיתוף מטה-נתונים כיתתיים משותפים בין תהליכי Java שונים. זה ניתן להשיג דרך השלבה של שלושה שלבים:
1. קביעת המחלקות לארכיב: השתמש במפעיל Java כדי ליצור רשימת קבצים לשיתוף, זה יכול להתרחש דרך הפרמטרים הבאים:
$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld
יצירת ארכיב AppCDS: השתמש במפעיל Java ליצירת הארכיב מרשימת הקבצים שיש להשתמש בו עבור Application CDS, זה יכול להתרחש דרך הפרמטרים הבאים:
$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
שימוש בארכיב AppCDS: השתמש במפעיל Java עם הפרמטרים הבאים כדי להשתמש ב-Application CDS.
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
אוסף הזבל G1 הופך לברירת המחדל ב-JDK 9. אוסף הזבל G1 ממנע כל אוסף של זבל מלא, אך כאשר תהליכי האוסף המתבצעים במקביל לא מחדירים את הזיכרון במהירות מספיקה, השפעתם נמשכת על המשתמשים. שינוי זה משפר את הלטנסיות הגרועה של G1 על ידי הפיכת אוסף הזבל המלא למקביל. אלגוריתם הסימון-ניקוי-קימוח מקבץ G1 מופקד כחלק מהשינוי הזה ויפעל כאשר תהליכי האוסף המתבצעים במקביל לא יכולים לשחזר את הזיכרון במהירות מספיקה. ### ממשק אוסף הזבל (JEP 304)
פרויקט זה הוא שינוי עתידני. הוא משפר את הבידוד של הקוד של אוספי הזבל השונים על ידי הצגת ממשק אוסף זבל משותף. השינוי מספק יותר גמישות לקוד הפנימי של אוספי הזבל. זה יעזור בעתיד להוסיף אוספי זבל חדשים מבלי לשנות את קוד המקור הקיים, וגם יסייע בהסרת או ניקוי האוספים הקודמים. ### הרחבות נוספות של תגיות שפת האוניקוד (JEP 314)
תכונה זו משפרת את java.util.Locale ו-APIs קשורים כדי ליישם הרחבות נוספות של תגיות השפה של BCP 47 של אוניקוד. מאז Java SE 9, תגיות השפה של BCP 47 U שנתמכות הן "ca" ו-"nu". פרויקט זה יוסיף תמיכה לתוספות הנוספות הבאות:
- cu (סוג מטבע)
- fw (יום ראשון של השבוע)
- rg (התעלמות מאזור)
- אזור זמן (tz)
כדי לתמוך בתוספות אלו, ישנם שינויים במגוון ממשקי תכנות (APIs) כדי לספק מידע בהתאם ל-U או לתוספות נוספות.
java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider
כדי לקדם את OpenJDK ולהפוך אותו למושך יותר למשתמשי הקהילה, התכונה הזו מספקת סט ברירת מחדל של תעוזות מכוללות (CA) ב-JDK. זה יהווה גם אומר שגם תוכניות ה-Oracle וה-Open JDK יהיו פונקציונלית זהות. רכיבי אבטחה קריטיים כמו TLS יעבדו כבררת המחדל בתצורות ה-OpenJDK העתידיות. 30. ### Thread-Local Handshakes (JEP 312)
זו תכונה פנימית של JVM לשיפור ביצועים. פעולת ההסתירה היא התראה שנפעלת עבור כל JavaThread בזמן שהלחץ נמצא במצב safepoint. ההתראה נפעלת או על ידי הלחץ עצמו או על ידי הלחץ VM בזמן שהלחץ נמצא במצב חסום. התכונה הזו מספקת דרך להפעיל התראה על לחצים בלתי כוללים על ידי ביצוע safepoint גלובלי של VM. להפוך את זה אפשרי וזול לעצור לחצים פרטיים ולא רק כל הלחצים או אף אחד. 31. ### הקצאת Heap על יחידות זיכרון חלופיות (JEP 316)
יישומים הפכו להיות אכזבה של זיכרון, יש עלייה ביישומים סגנוניים לעניין ענן, בסיסי נתונים בזיכרון, יישומים לזרימה. כדי להגיב לשירותים אלו, קיימים מגוון של ארכיטקטורות זיכרון. התכונה הזו משפרת את יכולות VM HotSpot להקצות את רגע ה-Java object heap על יחידת זיכרון אלטרנטיבית, כמו NV-DIMM, בהגדרה של המשתמש. JEP זו פועלת ליחידות זיכרון אלטרנטיביות שיש להן סמנטיקה זהה לזו של DRAM, כולל סמנטיקת פעולות אטומיות, ולכן יש אפשרות להשתמש בהן במקום DRAM לעניין ה-object heap מבלי לבצע שינוי בקוד היישום הקיים.32. ### הסרת כלי יצירת כותרות נייטיביות – javah (JEP 313)
זהו שינוי ניהולי המטרתו להסיר את כלי javah מתוך JDK. פונקציותיו של הכלי הוספו לתוך javac
כחלק מ-JDK 8, שמספק אפשרות ליצירת קבצי כותרות נייטיביים בזמן הקומפילציה, ולכן השימוש ב-javah הפך מיותר.35. ### איחוד יער JDK למחסנית אחת (JEP 296)
במהלך השנים נוצרו יערים מגוונים בקוד מקור של JDK. יערים שונים מספקים יתרונות מסוימים, אך גם היו להם מגוון של חסרונות אופרציונליים. כחלק מהשינוי הזה, מספר יערי JDK מתוזגים ליער אחד כדי לפשט ולזרום את תהליכי הפיתוח.
Java 10 הוסיפה והסירה (כן, זה לא טעות כתיב) API. Java 9 הכניסה שיפור בהפסקת שימוש במחלקות ובפונקציות מסוימות שנמצאות בתהליכים של הסרתן בגרסאות הבאות. API שהוסרו: ניתן למצוא את ה-API שהוסרו כאן. API שהוספו: התווספו 73 API חדשים ב-Java 10. ניתן למצוא את ה-API שנוספו יחד עם השוואה כאן. בואו נתעכב על כמה הוספות:
- נוספו ממשקי List, Map & Set עם שיטה סטטית copyOf(Collection). זה מחזיר List, Map או Set לא ניתנים לשינוי המכילים את הערכים המסופקים. עבור List, אם הרשימה שניתנה נערכת לאחר מכן, הרשימה המוחזרת לא תשקף את השינויים האלה.
- Optional והשיפורים הראשוניים שלו מקבלים שיטה orElseThrow(). זה זהה בדיוק ל-get(), אך מסמך ה-Java מציין כי זו אפשרות מועדפת מעל get()
- המחלקה Collectors מקבלת שיטות שונות לאיסוף של אוספים לא-ניתנים לשינוי (Set, List, Map)
List actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// API חדש הוסיף - יוצר רשימה לא ניתנת לשינוי מרשימה קיימת.
List copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("רוברט דה נירו"); ייצור
// UnsupportedOperationException
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
String str = "";
Optional name = Optional.ofNullable(str);
// API חדש הוסיף - אפשרות מועדפת מעל שיטת get()
name.orElseThrow(); // same as name.get()
// API חדש הוסיף - Collectors.toUnmodifiableList
List collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("טום הנקס"); // ייצור
// UnsupportedOperationException
מסקנה
במאמר זה, עברנו דרך התוספות שונות בתכונות של Java 10. אם יש לך תחושה שפספסנו משהו חשוב כאן, אנא הודיע לנו דרך התגובות. כפי שתמיד אפשר לבדוק את הקוד המלא ב-GitHub כאן.
Source:
https://www.digitalocean.com/community/tutorials/java-10-features