JavaRush /בלוג Java /Random-HE /Java 14: מה חדש?

Java 14: מה חדש?

פורסם בקבוצה
הבעיות של העולם הן הבעיות של העולם, וה-Java החדש עומד בלוחות הזמנים. כלומר, בדיוק פעם בחצי שנה. גרסת השחרור של Java 14 שוחררה ב-17 במרץ, והציגה מספר חידושים מעניינים לשפה המיועדת למפתחים. Java 14: מה חדש?  - 1ביניהם תמיכה ניסיונית עבור מילת המפתח הרשומה , תמיכה בהתאמת דפוסים באופרטור " instanceof ", NullPointerExceptions ידידותיים יותר למשתמש , "תצוגה מקדימה" מורחבת של בלוקי טקסט , מתג ברירת מחדל מעודכן ועוד הרבה יותר. נזכיר לך שכל החידושים ב-Java מתחילים בהצעות הרחבות ( JEP, Java Enhancement Proposals ). מפתחים מציעים שינויים, הם נבדקים על ידי ההורים ה"רשמיים" של Java, ואז חלק מהשינויים הללו מתקבלים, ולאחר מכן הם הופכים לחלק מה-JDK. ועכשיו - בערך הכל בסדר.

JEP 359: שיאים

רשומות, הידועות גם בשם Records, זמינות עבור JDK 14 במצב תצוגה מקדימה, וזה משהו חדש לחלוטין עבור Java. למעשה, לפנינו סוג חדש שפותח במהלך פרויקט Valhalla . רשומות דומות לספירות ומאפשרות לך לפשט את הקוד שלך. בעיקרו של דבר, הם מחליפים כיתות שיש להן מצב אך ללא התנהגות. במילים פשוטות, יש שדות, אין שיטות. במקרה של מחלקות, אנחנו צריכים לפעמים לכתוב הרבה קוד שחוזר על עצמו שלא תמיד נחוץ: קונסטרוקטורים, אקססוריז, equals(), hashCode(), toString() וכו'. כדי להימנע מהקוד החוזר הזה, Java מתכננת להשתמש ברשומה. הנה הגרסה הקלאסית:
final class Triangle {
 	public final int x;
public final int y;
public final int z;

    public Triangle(int x, int y, int z) {
         this.x = x;
         this.y = y;
    this.z = z;
    }
    // equals, hashCode, toString
בואו נעבור ל-Java 14 ונשתמש ברשומה:
public record Triangle(int x, int y, int z){}
זה הכל. שימו לב שההקלטות קיימות כרגע בצורת תצוגה מקדימה, אז כדי לנסות אותן בפועל צריך להוריד את jdk14 ולהזין את הפקודה:
javac —enable-preview —release 14 Triangle.java
שיאים הם שיעורים, אם כי עם מגבלות. הם לא יכולים להרחיב מחלקות אחרות או להכריז על שדות (למעט סופי פרטי שמתואמים לרכיבי הצהרת המדינה). הרשומות הן סופיות באופן מרומז ואינן יכולות להיות מופשטות. רשומות שונות ממחלקות רגילות בכך שאינן יכולות להפריד את ה-API שלהן מהייצוג שלה. אבל אובדן החופש מפצה על ידי דיוק מוגבר. גם רכיבי הרשומה הם סופיים באופן מרומז.

JEP 305: התאמת דפוסים למשל של (תצוגה מקדימה)

התכונה Pattern Matching , שהוצגה ב-Java 14 בתצוגה מקדימה, נועדה לשלב בדיקת סוג האובייקט וההמרה שלו ב- instanceof Operator. במילים אחרות, לפני Java 14 היה, למשל, הקוד הבא:
Object object = Violin;

if (object instanceof Instrument) {
    Instrument instrument = (Instrument) object;
    System.out.println(instrument.getMaster());
}
כפי שאתה יכול לראות, עלינו להטיל את האובייקט למחלקה שבה אנו רוצים להשתמש בשיטות שלה. כעת Java 14 ותכונת התאמת התבניות המחוברת מאפשרת לך לצמצם את הקוד לערכים הבאים:
Object object = Violin;

if (object instanceof Instrument instrument){
    System.out.println(instrument.getMaster());
}

JEP 343: כלי אריזה (אינקובטור)

ל-JDK 8 היה כלי javapackager המיועד ל-JavaFX. עם זאת, בעקבות ההפרדה של JavaFX מ-Java עם שחרורו של JDK 11, ה-javapackager הפופולרי כבר לא היה זמין. Javapackager היה כלי אריזה. זה אפשר לארוז יישומי Java בצורה כזו שניתן להתקין אותם כמו כל שאר התוכניות "רגילות". לדוגמה, צור קבצי exe עבור משתמשי Windows והפעל יישום Java כמו אדם - בלחיצה כפולה. כמובן שכלי כזה חסר מאוד, אז JEP 343 הציג כלי חדש, jpackage , אשר אורז יישום Java לחבילה ספציפית לפלטפורמה המכילה את כל התלות הנדרשת. פורמטי חבילה נתמכים עבור פלטפורמה ספציפית:
  • לינוקס: דב וסל"ד
  • macOS: pkg ו-dmg
  • Windows: MSI ו-EXE

JEP 345: הקצאת זיכרון NUMA-Aware עבור G1

JEP 345 משמש אך ורק ליישום תמיכה ב-NUMA (גישה לא אחידה לזיכרון). אלו הן ארכיטקטורות גישה הטרוגניות לזיכרון, דרך להגדיר אשכול מיקרו-מעבדים למערכת מרובת מעבדים שבה ניתן להפיץ זיכרון באופן מקומי: כל ליבת מעבד מקבלת כמות קטנה של זיכרון מקומי, בעוד לליבות אחרות יש גישה אליה. JEP 345 מתכנן לצייד את אוסף האשפה G1 כדי למנף ארכיטקטורות כאלה. בין היתר, גישה זו עוזרת לשפר את הביצועים במכונות חזקות מאוד.

JEP 349: JFR Event Streaming

Java Flight Recorder (JFR) הוא כעת חלק מ-OpenJDK ולכן זמין באופן חופשי. JDK 14 מוסיף API למעקב בזמן הטיסה של אירועי JFR (JDK Flight Recorder), בפרט לארגון ניטור רציף של יישומים פעילים ולא פעילים. אותם אירועים נרשמים כמו לאפשרות הלא-סטרימינג, עם תקורה של פחות מ-1%. כך האירועים יוזרמו במקביל לאופציה ללא סטרימינג. עם זאת, JEP 349 אסור לאפשר התקשרות חוזרת סינכרונית עבור הצרכן המקביל. אפילו נתונים מרשומות המאוחסנות בזיכרון הביניים לא אמורים להיות נגישים. מבחינה טכנית, חבילת jdk.jfr.consumer במודול jdk.jfr תורחב עם פונקציונליות לגישה אסינכרונית לאירועים.

JEP 352: מאגרי בייט ממופים לא נדיפים

כפי שאתה יודע, Java NIO (New IO) File API קיים מאז JDK 1.4, ואז הוצג שיפור חדש בשם Path. Path הוא ממשק שמחליף את המחלקה java.io.File כייצוג של קובץ או ספרייה כאשר אנו עובדים ב-Java NIO. JEP 352 מרחיב את MappedByteBuffer לטעינת חלק מנתוני הקבצים לזיכרון לא נדיף (NVM). זיכרון המחשב הזה, שבו הנתונים לא יאבדו גם אם הכוח יכבה (נקרא לעתים קרובות זיכרון לקריאה בלבד), משמש לאחסון נתונים לצמיתות. הצעת שיפור Java זו מספקת מודול ומחלקה חדשים ל-JDK API: מודול jdk.nio.mapmode, המציע מצבים חדשים (READ_ONLY_SYNC, WRITE_ONLY_SYNC) ליצירת מאגרי בתים ממופים (MappedByteBuffer) המתייחסים ל-NVM.

JEP 358: NullPointerExceptions שימושי

NullPointerExceptions יהיו כעת ידידותיים יותר למתכנת. במובן זה שתיאור החריג יהיה הרבה יותר אינפורמטיבי מבעבר. הסיבה לכך היא שה-JVM לימדו לנתח בצורה מדויקת יותר הוראות קוד בתים של תוכנית, והוא יכול לציין איזה משתנה מוביל לערך אפס. נניח שיש לנו את הקוד:
a.getMessage().getUserInfo().getName()
בכל אחד מה-Java העדכניים ביותר, נקבל את יומן השגיאות הרגיל, שאינו עונה על השאלה מי בדיוק null:
Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:12)
והנה מה ש-Java 14 ייתן לך אם תחליט לנסות את תכונת התצוגה המקדימה הזו:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "UserInfo().getName()" because the return value of "Message().getUserInfo()" is null
	at Main.main(Main.java:12)
השרשרת הזו הרבה יותר מובנת ומאפשרת להתמודד עם השגיאה הרבה יותר מהר.

JEP 361: Switch Expressions (סטנדרטי)

מפעיל ה-Switch המעודכן היה זמין ב-Java 12 ו-13 הקודמים, אך רק כתכונת תצוגה מקדימה, כלומר, הוא לא הופעל כברירת מחדל. עכשיו ב-JDK 14 הכל עובד מחוץ לקופסה. Java 14 מציגה צורה פשוטה חדשה של בלוק המתג עם תוויות מקרה L -> .... הטופס החדש מפשט את הקוד במקרים מסוימים. הנה כמה דוגמאות. נניח שיש לנו מנה שמתארת ​​את ימות השבוע. אנחנו יכולים לכתוב קוד קלאסי (קדם-Java 14):
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
והנה אפשרות באמצעות Java 14:
switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
אתה יכול גם לכתוב בלוקים מרובי שורות ולהחזיר ערך עם מילת המפתח החדשה תשואה:
int result = switch (s) {
    case "Working from Home" -> 1;
    case "Working from Office" -> 2;
    default    -> {
        System.out.println("Neither Home nor Office… Cafe? Car? Park?...");
        yield 0;
    }
};
יש עוד כמה דברים חשובים שכדאי לזכור בעת השימוש במתגים החדשים . בפרט, עליך לזכור שהאפשרויות חייבות להיות ממצות. כלומר, לכל הערכים האפשריים חייבת להיות תווית מתג מתאימה. מכיוון שתשואה היא כעת מילת מפתח, מחלקה בשם תשואה אפשרית ב-Java 14. באופן כללי, אם אתה רוצה ללמוד כיצד להשתמש במתגים המעודכנים, עבור אל JEP 361 ולמד. יש שם הרבה מידע מעניין.

JEP 362: הוצא משימוש יציאות Solaris ו-SPARC

אין זה סביר שרבים מהקוראים שלנו זוכרים את מערכת ההפעלה Solaris . מערכת הפעלה זו מבוססת UNIX, שנוצרה על ידי הוריה של Java, Sun Microsystems, שימשה בעיקר עבור שרתים בארכיטקטורת SPARC... יותר מדי מילים לא מוכרות לסנטימטר רבוע? לא נורא: JEP 362 מסיים את התמיכה בפלטפורמות Solaris/SPARC, Solaris/x64 ו-Linux/SPARC. כלומר, הפורטים שלהם הוצאו משימוש, וסביר להניח שבעתיד הם יוסרו מ-OpenJDK. עם זאת, גרסאות ישנות יותר של Java (לפני JDK 14) לגבי יציאות Solaris/SPARC, Solaris/x64 ו-Linux/SPARC צריכות לעבוד ללא שינוי. אם אתה חובב היסטוריה ומתעניין בטכנולוגיות מהעבר הלא כל כך רחוק, כנס לוויקיפדיה וקרא על ארכיטקטורת SPARС .

JEP 363: הסר את אספן האשפה במקביל לסימון סימנים (CMS).

אוסף האשפה של CMS (Concurrent Mark Sweep) מיועד להסרה מכיוון שלפני שנתיים הוא סומן כמיושן ולא מתוחזק. עם זאת, משתמשים של גרסאות ישנות יותר של Java המשתמשות ב-CMS GC יכולים לנשוף - מטרת ה-JEP הזה היא לא להסיר את הבונה ממהדורות קודמות של JDK. בנוסף, השילוב של אלגוריתמי איסוף האשפה ParallelScavenge ו-SerialOld (פועלים עם האפשרויות "-XX:+UseParallelGC -XX:-UseParallelOldGC") הוצא משימוש.

JEP 364: ZGC ב-macOS ו- JEP 365: ZGC ב-Windows

יש אספן אשפה מעניין בשם Z Garbage Collector (ZGC) . הוא פועל במצב פסיבי, ומנסה למזער עיכובים עקב איסוף אשפה: זמן העצירה בעת שימוש ב-ZGC אינו עולה על 10 אלפיות השנייה. זה יכול לעבוד עם ערימות קטנות וערימות ענקיות (כאלה שתופסים טרה-בייט רבים). JEP 364 ו-JEP 365 הם למעשה תאומים. JEP 364 מביא את Z Garbage Collector ל-MacOS. חלק מה-JEP מתאר גם את פונקציונליות האספן לשחרור זיכרון מכשיר שאינו בשימוש, כפי שצוין ב- JEP 351 , זה קורה עם Java 13. הטמעת ZGC ב-macOS מורכבת משני חלקים:
  • תמיכה בזיכרון רב מיפוי ב-macOS
  • תמיכת ZGC לשמירת זיכרון רציפה
JEP 365 מספק תמיכה עבור ZGC כבר ב-Windows, וגם במצב ניסיוני. זה כדלקמן:
  • תמיכה בזיכרון רב מיפוי
  • תמיכה במיפוי זיכרון המבוסס על קובץ העמוד למרחב כתובות שמור
  • תמיכה במיפוי וביטול מיפוי של חלקים שרירותיים של הערימה
  • תמיכה לביצוע וללא התחייבות של חלקים שרירותיים של הערימה

JEP 366: הוצא משימוש השילוב של ParallelScavenge + SerialOld GC

ה-JEP הזה מבטל את השילוב של אלגוריתמי איסוף אשפה מקבילים ואלגוריתמים Serial Old. היה צורך להפעיל שילוב זה באופן ידני באמצעות הפרמטרים של שורת הפקודה -XX: + UseParallelGC -XX: -UseParallelOldGC. המחברים מאמינים כי השילוב הוא מאוד ספציפי, אך גם דורש מאמץ תחזוקה משמעותי. אז עכשיו האפשרות -XX: UseParallelOldGC הוצאה משימוש ואזהרה תופיע אם נעשה שימוש.

JEP 367: הסר את Pack200 Tools and API

Pack200 הוא פורמט ארכיון המותאם לאחסון קבצי מחלקות Java מהידור. כלי זה סומן שהוצא משימוש מאז Java 11. כעת הוכרזו רשמית כלי ה-API של pack200, unpack200 ו-Pack200 להסרה מחבילת java.util.jar . הטכנולוגיה הזו הוצגה בחזרה ב-Java 5 כאמצעי להתמודדות עם רוחב פס מוגבל מאוד (מודמים, זה מפחיד לומר ולזכור, 56k) ושטח אחסון לא מספיק בכוננים קשיחים. לפני זמן מה, Java 9 הציגה סכימות דחיסה חדשות. מפתחים מוזמנים להשתמש ב-jlink .

JEP 368: בלוקים של טקסט (תצוגה מקדימה שנייה)

בלוקי טקסט הופיעו לראשונה ב-Java 13. הם מילוליות של מחרוזות מרובות שורות שמונעות את הצורך ברוב רצפי הבריחה, פורמטים אוטומטית את המחרוזת, וגם מאפשרים למפתח לעצב את המחרוזת במידת הצורך. תכונה שימושית זו זמינה כעת ב-Java 14 (תצוגה מקדימה שנייה). המטרה העיקרית של בלוקים של טקסט היא לשפר את הטיפול במילים מילוליות מרובות שורות מבלבלות. זה מפשט מאוד את הקריאה והכתיבה של שאילתות SQL, קוד HTML ו-XML ו-JSON. HTML לדוגמה ללא קוביות טקסט:
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, JavaRush Student</p>\n" +
              "    </body>\n" +
              "</html>\n";
כיצד לייצג את אותו הדבר עם בלוקי טקסט:
String html = """
              <html>
                  <body>
                      <p>Hello, JavaRush Student</p>
                  </body>
              </html>
              """;
המפריד הפותח הוא רצף של שלושה תווים במירכאות כפולות ("" "), ואחריהם אפס רווחים או יותר, ולאחר מכן מפריד שורה. התוכן מתחיל בתו הראשון אחרי מפריד השורות של המפריד הפותח. המפריד הסוגר הוא נבחרו רצף של שלושה תווים במירכאות כפולות " _ ) כך שניתן יהיה להציג את התווים מבלי לברוח, וגם להבחין חזותית בין בלוק טקסט למחרוזת מילולית. בתחילת 2019, JEP 355 הציע בלוקים של טקסט כהמשך ל-JEP 326 (Raw String literals), אך הם הוסרו. מאוחר יותר באותה שנה, JDK 13 הציג את תכונת התצוגה המקדימה של בלוק טקסט, וכעת Java 14 הוסיפה שני רצפי בריחה חדשים. זהו מסיים שורה, מסומן \, והשני הוא עבור רווח בודד, מסומן /s. דוגמה לשימוש בשורות חדשות ללא בלוקי טקסט:
String literal = "This is major Tom to Ground Control " +
"I am stepping through the door... " +
"Wait… What???";
ועכשיו עם רצף הבריחה \<line-terminator>:
String text = """
                This is major Tom to Ground Control \
                I am stepping through the door... \
                WaitWhat???\
                """;
רצף הבריחה \s משמש כדי לקחת בחשבון את הרווח הלבן הנגרר, שהקומפיילר מתעלם ממנו כברירת מחדל. הוא שומר על כל הרווחים הלבנים שלפניו. דוגמא:
String text1 = """
               line1
               line2 \s
               line3
               """;

String text2 = "line1\nline2 \nline3\n";
text1והם text2זהים.

JEP 370: Foreign-Memory Access API (אינקובטור)

לספריות ותוכניות Java פופולריות רבות יש גישה לזיכרון חיצוני. לדוגמה, Ignite, MapDB, Memcached ו-Netty ByteBuf API. בכך, הם יכולים להימנע מהעלות והאי-חיזוי הקשורים לאיסוף אשפה (במיוחד כאשר הם משרתים מטמונים גדולים), לשתף זיכרון על פני מספר תהליכים, ולעשות סדרה וסיריאליזציה של תוכן זיכרון על ידי מיפוי קבצים בזיכרון (לדוגמה, באמצעות mmap). עם זאת, ל-Java API עדיין אין פתרון מתאים לגישה לזיכרון חיצוני. JDK 14 כולל תצוגה מקדימה של Foreign-Memory Access API , המאפשר ליישומי Java לגשת בצורה מאובטחת ויעילה לאזורי זיכרון מחוץ לערמת ה-JVM באמצעות ההפשטות החדשות של MemorySegment, MemoryAddress ו-MemoryLayout.

מסקנות

אז מה אתה חושב? בהשוואה ל-Java 13, ה-Java 14 החדש מציע שיפורים חשובים רבים יותר במגוון תחומים. סביר להניח שהחשוב ביותר עבור מפתחים יהיה המתג המעודכן, חריגים מורחבים NullPointerExceptions ורשומות. או לא?.. אל תשכחו לנסות את התכונות החדשות של Java 14, זה מאוד שימושי גם למתחילים. בהצלחה עם הלימודים שלך!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION