JavaRush /בלוג Java /Random-HE /Java 11 שוחרר: תכונות ויכולות חדשות

Java 11 שוחרר: תכונות ויכולות חדשות

פורסם בקבוצה
בעבר, גרסאות חדשות של Java הופיעו לעתים רחוקות ובעיכובים. כעת אורקל שומרת בהצלחה על הקצב שקבעה לעצמה: "ג'אווה חדשה כל שישה חודשים". אז לפני כמה ימים, בהחלט לפי לוח הזמנים, קיבלנו סוף סוף את Java SE 11 ואת ההטמעה של ה-JDK (ערכת פיתוח Java). Java 11 יצא לאור: תכונות ויכולות חדשות - 1כמו תמיד, הגרסה החדשה תהיה תואמת לישנה, ​​והתמיכה ב-Java 11 תסתיים לא לפני דצמבר 2026.

תכונות חדשות ב-Java SE 11 (גלוי למפתחים)

נזכיר כי ב-Java, שינויים מתבצעים באמצעות יישום ה-JEP "JDK Enhancement Proposal". JEP היא הצעה לשיפור OpenJDK ועשויה להיות מאושרת, לעכב או לדחות. כלומר, בעצם, אוסף של JEPs הוא אסטרטגיית פיתוח עבור OpenJDK. בסוגריים מרובעים לפני ה"תכונה" החדשה נציין את מספר ה-JEP המתאים. [323] תחביר משתנה מקומי לפרמטרי למבדה - תחביר var עבור פרמטרים למבדה Java 10 הציגה את מילת המפתח var, מה שאיפשר לא לציין במפורש את סוג המשתנה המקומי. זה פשט את הקוד. JEP 323 מרחיב את השימוש בתחביר זה עם ביטויי למבדה. דוגמה פשוטה:
list.stream ()
                 .map ((var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
כפי שכותב סיימון ריטר , אוונגליסט ג'אווה ידוע, מתכנת ג'אווה מנוסה יציין ששימוש ב-var במקרה זה עשוי להיות מיותר, מכיוון שניתן להחליף את הקוד שלמעלה בקוד הבא:
list.stream ()
                  .map (s -> s.toLowerCase ())
                  .collect (Collectors.toList ());
מדוע, אם כן, לתמוך ב-var? יש רק מקרה אחד מיוחד - כאשר אתה רוצה להוסיף הערה לפרמטר למבדה. זה לא יכול להיעשות בלי סוג כלשהו מעורב, וכדי להימנע משימוש בסוג מפורש, אנחנו יכולים לפשט הכל באמצעות var כמו זה:
list.stream ()
                 .map ((@ Notnull var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
[330] השקת תוכניות קוד מקור של קובץ יחיד שיפור מפעיל ה-Java כדי להפעיל תוכנית כקובץ יחיד עם קוד מקור Java. Java זוכה לעתים קרובות לביקורת על התחביר המפורש וה"טקס" הרב-שלבי של השקת אפילו יישום טריוויאלי. לפעמים זה מפחיד מתחילים. כדי לכתוב אפליקציה שפשוט מדפיסה " Hello World! " ", עליך לכתוב מחלקה עם voidשיטה ראשית סטטית ציבורית ולהשתמש ב- System.out.println. לאחר שעשית זאת, עליך להרכיב את הקוד באמצעות javac . לבסוף, לאחר מכן, תוכל להפעיל את האפליקציה, שתציג את הברכה הרעה (כמובן, סביבת הפיתוח המשולבת, גם IDEA וגם זו המובנית ב- JavaRush , מבצעת את "קסם השקת האפליקציה" הזה בעצמה - הערת עורך ). בואו נהיה כנים: ברוב שפות התכנות, הסקריפט בפועל להפעלת תוכניות נראה הרבה יותר פשוט. JEP 330 מבטל את הצורך להדר יישום של קובץ בודד, אז עכשיו אם אתה משתמש בשורת הפקודה, פשוט הקלד
java HelloWorld.java
מפעיל ה-Java יזהה שהקובץ מכיל קוד מקור של Java ויקמפל את הקוד לקובץ מחלקה לפני ביצועו. אתה יכול למקם פרמטרים אחרי או לפני שם קובץ קוד המקור. אלה שממוקמים אחרי השם מועברים כפרמטרים בעת הפעלת היישום. אלה שממוקמים לפני השם מועברים כפרמטרים למפעיל Java לאחר הידור הקוד. אפשרויות ספציפיות למהדר (כגון classpath) יועברו גם ל- javac לצורך הידור. דוגמא. קַו:
java -classpath / home / foo / java Hello.java Bonjour
יהיה שווה ערך לשורות האלה:
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] לקוח HTTP (סטנדרטי) - תמיכה ב-HTTP Client API עברה תקן. JDK 9 הציג API חדש לתמיכה בפרוטוקול HTTP Client (JEP 110) . מכיוון ש-JDK 9 הציגה גם את מערכת ה- Java Platform Module System (JPMS) , ממשק API זה נכלל כמודול חממה (אלו מודולים לספק למפתחים ממשקי API חדשים שעדיין לא הפכו לסטנדרטיים ב-Java SE, בזמן שממשקי ה-API "חיים" נמצאים מוכן להסרה - מפתחים יכולים לנסות ממשקי API חדשים ולנסות לספק משוב). לאחר ביצוע השינויים הדרושים (API זה עודכן ב-JDK 10), ה-API יכול להפוך לחלק מהתקן. אז, ממשק ה-API של HTTP Client כלול כעת באופן רשמי ב-Java SE 11 . זה מציג מודול וחבילה חדשים עבור ה-JDK, java.net.http . הסוגים החדשים העיקריים הם: HttpClient HttpRequest HttpResponse WebSocket ניתן להשתמש ב-API זה באופן סינכרוני או אסינכרוני. במצב אסינכרוני, CompletionFuturesומשמשים CompletionStages. [320] הסר את מודולי Java EE ו-CORBA עם הצגת מערכת ה- Java Platform Module System (JPMS) בגרסה התשיעית של Java, אפשר היה לפצל את קובץ ה-rt.jar המונוליטי למספר מודולים. בנוסף, JPMS מאפשר לך ליצור סביבת זמן ריצה של Java הכוללת רק את המודולים הדרושים לאפליקציה שלך, מה שמקטין מאוד את גודלה. עם גבולות מודול מוגדרים בשקיפות, הרבה יותר קל להסיר חלקים מיושנים של Java API - זה מה שעושה JEP 320. המטא- מודול java.se.ee כולל שישה מודולים שלא יהיו חלק מתקן Java SE 11 ולא ייכללו ב-JDK:
  • קורבה
  • עִסקָה
  • הַפעָלָה
  • xml.bind
  • xml.ws
  • xml.ws.annotation
מודולים אלה הוצאו משימוש ב-JDK 9 ולא נכללו כברירת מחדל בקומפילציה או בביצוע. המשמעות היא שאם ניסיתם להדר או להפעיל אפליקציה שמשתמשת בממשקי API של המודולים האלה ב-JDK 9 או JDK 10, זה נכשל. אם אתה משתמש בממשקי ה-API של המודולים האלה בקוד שלך, תצטרך לספק אותם כמודול או ספרייה נפרדים.

ממשקי API חדשים

מספר רב של ממשקי API חדשים ב-JDK 11 הופיעו הודות להכללת מודולי ה-HTTP Client ו- Flight Recorder בתקן השפה . לרשימה מלאה של ממשקי API, ראה את ההשוואה המקיפה הבאה של גרסאות שונות של ה-JDK , שנערכה על ידי Gunnar Morling. ובהערה זו נפרט כמה שיטות חדשות שאינן כלולות במודולים java.net.http , jdk.jfr ו- java.security . java.lang.String ללא ספק אחד השינויים החשובים ביותר למחרוזת ב-API של JDK 11, ישנן מספר שיטות חדשות ושימושיות.
  • boolean isBlank (): מחזירה true אם המחרוזת ריקה או מכילה רק רווחים, אחרת false.

  • Stream lines(): מחזירה זרם של קווים שחולצו ממחרוזת זו, מופרדים על ידי מסימי שורות.

  • String repeat (int): מחזירה מחרוזת שהערך שלה הוא השרשור של אותה מחרוזת שחוזרת על עצמה int times.

  • String strip (): מחזירה מחרוזת שכל הרווחים הוסרו לפני או אחרי התו הראשון שאינו רווח.

  • String stripLeading (): מחזירה מחרוזת שכל הרווחים עד התו הראשון שאינו רווח הוסרו.

  • String stripTrainling (): מחזירה מחרוזת עם כל הרווחים המופיעים לאחר הסרת התו האחרון שאינו רווח.
strip()השיטה כבר עשתה משהו דומה trim (), אבל לפי רווחים השיטות האלה מתכוונות לדברים שונים. במקרה, trim()רק רווחים נחתכים, וב- strip()גם תווים מיוחדים, כגון טאבים. java.lang.StringBuffer java.lang.StringBuilder שתי המחלקות הללו מכילות שיטה חדשה compareTo ()שמקבלת StringBuffer/ StringBuilderומחזירה int. שיטת ההשוואה המילונית דומה לשיטה החדשה compareTo() CharSequence. java.io.ByteArrayOutputStream
  • void writeBytes (byte []): כותב את כל הבתים של הפרמטר לזרם הפלט של java.io.FileReader
יש כאן שני בנאים חדשים שמאפשרים לך לציין Charset. java.io.FileWriter ארבעה בנאים חדשים המאפשרים לך לציין Charset. java.io.InputStream
  • io.InputStream nullInputStream (): מחזיר InputStream, שאינו קורא אף בתים. כיצד להשתמש בשיטה זו? אתה יכול לחשוב על זה כמשהו כמו /dev/null כדי לזרוק פלט שאתה לא צריך, או להחדיר קלט שתמיד מחזיר אפס בתים.
java.io.OutputStream
  • io.OutputStream nullOutputStream ()
java.io.Reader
  • io.Reader nullReader ()
java.io.Writer
  • io.Writer nullWriter ()
דמות java.lang
  • String toString (int): זהו עומס יתר של שיטה קיימת, אך משתמש ב-int במקום char.
java.lang.CharSequence
  • int compare (CharSequence, CharSequence): משווה מבחינה לקסיקוגרפית שני מקרים CharSequence. מחזירה ערך שלילי, אפס או ערך חיובי אם הרצף הראשון קטן, שווה או גדול מהשני מבחינה לקסיקוגרפית, בהתאמה.
java.lang.ref.Reference
    lang.Object clone (): אוונגליסט ג'אווה סיימון ריטר מודה שהשיטה הזו מבלבלת אותו. המחלקה Referenceלא מיישמת ממשק Cloneableושיטה זו תמיד תזרוק חריג CloneNotSupportedException. עם זאת, המומחה מציע ששיטה זו תהיה שימושית למשהו בעתיד.
java.lang.Runtime java.lang.System אין כאן שיטות חדשות. רק נזכיר שהשיטה runFinalizersOnExit ()הוסרה משתי המחלקות הללו, מה שעלול לגרום לבעיות תאימות. java.lang.Thread אין שיטות נוספות, רק נזכיר שהן destroy ()הוסרו stop (Throwable). עם זאת stop (), שאינו דורש ויכוחים, עדיין זמין. אנא זכור זאת מכיוון שעשויות להיות בעיות תאימות. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer בכל המחלקות הללו, מפתחי השפה הוסיפו שיטה mismatch ()שמוצאת ומחזירה את האינדקס היחסי של אי התאמה ראשונה בין מאגר זה למאגר נתון. java.nio.channels.SelectionKey
  • int interestOpsAnd (int)

  • int interestOpsOr (int)
java.nio.channels.Selector
  • int select (java.util.function.Consumer, long): בוחר ומבצע פעולה על מקשים שהערוצים המתאימים להם מוכנים לפעולות קלט/פלט. הפרמטר הארוך הוא פסק זמן.

  • int select (java.util.function.Consumer): עובד כמו השיטה לעיל, אך ללא פסק הזמן.

  • int selectNow (java.util.function.Consumer): עובד כמו השיטה לעיל, רק שהוא לא חוסם.

java.nio.file.Files
  • String readString (Path): קורא את כל התוכן מקובץ למחרוזת, מפענח בתים לתווים באמצעות קידוד UTF-8 .

  • String readString (Path, Charset): עובד כמו השיטה לעיל, אבל מפענח בתים לתווים באמצעות Charset.

  • Path writeString (Path, CharSequence, java.nio.file. OpenOption []): אם תכתוב רצף של תווים CharSequenceלקובץ, תווים אלה יקודדו לבייטים (באמצעות UTF-8 ).

  • Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption []): עובד כמו השיטה לעיל, רק התווים מקודדים לבייטים באמצעות Charset.
java.nio.file.Path
  • Path(String, String[]): מחזירה את הנתיב, הופך מחרוזת נתיב או רצף של מחרוזות שבשילוב יוצרות מחרוזת נתיב.

  • נתיב (net.URI): מחזיר את הנתיב על ידי שינוי ה-URI.
java.util.Collection
  • Object [] toArray (java.util.function.IntFunction): מחזירה מערך המכיל את כל האלמנטים באוסף זה, תוך שימוש בפונקציית המחולל שסופקה כדי להפיץ את המערך המוחזר.
java.util.concurrent.PriorityBlockingQueue java.util.PriorityQueue
  • void forEach (java.util.function.Consumer): מבצע את הפעולה שצוינה על כל רכיב Iterable עד שכל הרכיבים עברו עיבוד או שהפעולה זורקת חריגה.

  • boolean removeAll (java.util.Collection): מסיר את כל הרכיבים של אוסף זה הכלולים גם באוסף שצוין (פעולה אופציונלית).

  • boolean removeIf (java.util.function.Predicate): מסיר את כל הרכיבים של אוסף זה העונים על הפרדיקט הנתון.

  • boolean retainAll (java.util.Collection): שומר רק על הרכיבים באוסף זה הכלולים באוסף שצוין (פעולה אופציונלית).
java.util.concurrent.TimeUnit
  • long convert (java.time.Duration): ממירה את משך הזמן הנתון ליחידה זו.
java.util.function.Predicate
  • Predicate not(Predicate): מחזירה פרדיקט שהיא שלילה של הפרדיקט הנתון.
לדוגמה, הקוד הבא:
lines.stream ()

.filter (s ->! s.isBlank ())
ניתן להמיר לזה:
lines.stream ()

.filter (Predicate.not (String :: ISBLANK))
ואם אנו משתמשים בייבוא ​​סטטי, אז זה מה שנקבל:
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalJava.util.OptionalLong.
  • boolean isEmpty (): מחזירה true אם אין ערך , אחרת false .
java.util.regex.Pattern
  • Predicate asMatchPredicate (): מומחה ג'אווה, סיימון ריטר, מאמין שאולי מסתתרת כאן פנינה אמיתית של JDK 11 API. שיטה זו יוצרת פרדיקט שבודק האם דפוס זה תואם למחרוזת קלט נתונה.
java.util.zip.Deflater
  • int deflate (ByteBuffer): דוחס את נתוני הקלט וממלא את המאגר שצוין בנתונים דחוסים.

  • int deflate (ByteBuffer, int): דוחס את נתוני הקלט וממלא את המאגר שצוין בנתונים דחוסים. מחזירה את הכמות בפועל של נתונים דחוסים.

  • void setDictionary (ByteBuffer): מגדיר את המילון הנתון לדחיסה לבייטים במאגר הנתון. זהו עומס יתר של שיטה קיימת שיכולה כעת לקבל מערך ByteBuffer, ולא מערך בתים.

  • void setInput (ByteBuffer): מגדיר את נתוני הקלט לדחיסה. זה גם עומס יתר של שיטה קיימת.
java.util.zip.Inflater
  • int inflate (ByteBuffer): פורק בתים למאגר שצוין. מחזירה את המספר האמיתי של בתים לא דחוסים.

  • void setDictionary (ByteBuffer): מגדיר את המילון הנתון לבייטים במאגר הנתון. היא צורה עמוסה מדי של שיטה קיימת.

  • void setInput (ByteBuffer): מגדיר את נתוני הקלט לביטול דחיסה. צורה עמוסה מדי של שיטה קיימת.
javax.print.attribute.standard.DialogOwner זוהי מחלקה חדשה ב-JDK 11 והיא מחלקת מאפיינים המשמשת לתמיכה בבקשות הדפסה או התאמה אישית שיוצגו על גבי כל החלונות או חלון מסוים. javax.swing.DefaultComboBoxModel javax.swing.DefaultListModel
  • void addAll (Collection): מוסיף את כל האלמנטים הקיימים באוסף.

  • void addAll (int, Collection): מוסיף את כל האלמנטים הקיימים באוסף, החל מהאינדקס שצוין.
javax.swing.ListSelectionModel
  • int [] getSelectedIndices (): מחזירה מערך של כל האינדקסים שנבחרו במודל הנבחר בסדר עולה.

  • int getSelectedItemsCount (): מחזירה את מספר הפריטים שנבחרו.
jdk.jshell.EvalException
  • shell.JShellException getCause (): מחזיר את הסיבה הניתנת לזריקה בלקוח הביצוע המוצג על ידי EvalException זה, או null אם הסיבה אינה קיימת או אינה ידועה.

תכונות שאינן מפתחים של Java 11

[181] בקרת גישה מבוססת Nest Java ושפות אחרות תומכות במחלקות מקוננות דרך מחלקות פנימיות. כדי שזה יעבוד, המהדר חייב לבצע טריקים מסוימים. לדוגמה:
public class Outer {
    private int outerInt;

     class Inner {
       public void printOuterInt() {
         System.out.println("Outer int = " + outerInt);
       }
     }
   }
המהדר משנה את זה כדי לייצר משהו כמו הבא לפני ההידור:
public class Outer {
      private int outerInt;

      public int access$000() {
        return outerInt;
      }

    }


    class Inner$Outer {

      Outer outer;

      public void printOuterInt() {
        System.out.println("Outer int = " + outer.access$000());
      }
    }
למרות שמבחינה לוגית המחלקה הפנימית היא חלק מאותו קוד כמו המחלקה החיצונית, היא מורכבת כמחלקה נפרדת. לכן, פעולה זו דורשת שיטת join סינתטית שחייבת להיווצר על ידי המהדר כדי לספק גישה לשדה הפרטי של המחלקה החיצונית. JEP זה מציג את המושג קינים, כאשר שני חברים באותו קן (חיצוני ופנימי בדוגמה שלנו) הם חברים מקננים. שתי תכונות חדשות מוגדרות עבור פורמט קובץ הכיתה: NestHost ו- NestMembers . שינויים אלה שימושיים עבור שפות אחרות התומכות במחלקות מקוננות וב-bytecode. פונקציה זו מציגה שלוש שיטות חדשות עבור java.lang.Class : Class getNestHost () Class [] getNestMembers () boolean isNestmateOf (Class) [309] קבועי Class-File Dynamic JEP זה מתאר הרחבה לפורמט הקובץ המחלקה כדי לתמוך בגרסה החדשה מאגר מתמיד בצורת CONSTANT_Dynamic. הרעיון של קבוע דינמי נראה כמו אוקסימורון, אבל בעצם אתה יכול לחשוב על זה כעל ערך סופי ב-Java 11. הערך של קבוע איגום לא נקבע בזמן הקומפילציה (בניגוד לקבועים אחרים), אלא משתמש ב-bootstrap שיטה לקביעת הערך בזמן ההובלה. לכן הערך הוא דינמי, אך מכיוון שהערך שלו נקבע פעם אחת בלבד, הוא גם קבוע. תכונה זו מיועדת בעיקר לאנשים המפתחים שפות ומהדרים חדשים שייצרו קובצי בתים וקבצי מחלקה כפלט להפעלה ב-JVM. [315] שפר את מהות Aarch64 JEP זה הוצע על ידי קהילת Red Hat. ה-JVM יכול כעת להשתמש בהוראות מיוחדות יותר הזמינות בערכת ההוראות של Arm 64. בפרט, זה משפר את הביצועים של המתודות , sin ()ומחלקת cos ()java.lang.Math . [318] אפסילון: אוסף אשפה ללא הפעלה כמו ב- JEP 315 , אתה יכול להודות ל-Red Hat על הצגתו של אוסף האשפה של אפסילון. אפסילון יוצא דופן בכך שהוא לא ממש אוסף אשפה! בעת יצירת אובייקטים חדשים, הוא מקצה זיכרון במידת הצורך, אך אינו תופס מקום שתפוס על ידי אובייקטים לא רשומים. " מה הטעם? ", - אתה שואל. מסתבר של"איסוף האשפה" הזה יש שני שימושים: log ()
  1. קודם כל, אספן האשפה הזה נועד להבטיח שאלגוריתמים חדשים של GC יוערכו במונחים של השפעת הביצועים שלהם. הרעיון הוא להריץ אפליקציה לדוגמה עם אפסילון וליצור קבוצה של מדדים. אלגוריתם איסוף האשפה החדש מופעל, אותן בדיקות מופעלות ואז התוצאות מושוות.

  2. למשימות קצרות מאוד (תחשוב על פונקציות ללא שרת בענן) שבהן אתה יכול להבטיח שלא תחרוג מהזיכרון שהוקצה לערימה. זה יכול לשפר את הביצועים על ידי ביטול התקורה (כולל איסוף נתונים סטטיסטיים הדרושים כדי להחליט אם להפעיל את האספן) בקוד האפליקציה. אם שטח הערימה מיצה, ה-JVM עשוי להיות מוגדר שגוי באחת משלוש דרכים:
    • רגיל נקרא OutOfMemoryError.
    • בצע איפוס ערימה
    • הכונן הקשיח של JVM כשל וייתכן שהוא מבצע משימה אחרת (כגון הפעלת מאתר באגים).
[328]: Flight Recorder Flight Recorder הוא מסגרת רכישת נתונים ברמה נמוכה עבור ה-JVM. לפני JDK 11, זה היה תכונה מסחרית ב-Oracle JDK הבינארי. אורקל מבטלת כעת את ההבדלים הפונקציונליים בין ה-Oracle JDK ל-Build אחד מ-OpenJDK. הנה מה שעושה Flight Recorder :
  • מספק API להפקה וצריכת נתונים כאירועים
  • מספק מנגנון חיץ ופורמט נתונים בינאריים
  • מאפשר התאמה אישית וסינון של אירועים
  • ספק אירועים עבור ספריות OS, JVM HotSpot ו-JDK
יש כאן שני מודולים חדשים: jdk.jfr ו- jdk.management.jfr . [329] אלגוריתמים קריפטוגרפיים ChaCha20 ו- Poly1305. JEP זה עוסק בעדכון הצפנים המשמשים את ה-JDK. מקרה זה מיישם את אלגוריתמי ההצפנה ChaCha20 ו- ChaCha20-Poly1305 כפי שצוין ב-RFC 7539. ChaCha20 הוא צופן זרם חדש יחסית שיכול להחליף את צופן RC4 הישן והלא מאובטח . [333] ZGC: A Sccalable Low-Latency Garbage Collector אספן אשפה ניסיוני שניתן להרחבה עם אחזור נמוך. מיועד לשימוש עם יישומים הדורשים ערימה גדולה (רב-גיגה-בתים) והשהייה נמוכה. הוא משתמש בערימת דור בודד ועושה את רוב (אך לא את כל) עבודת איסוף האשפה במקביל ליישום. [332] Transport Layer Security (TLS) 1.3 TLS 1.3 (RFC 8446) הוא תיקון מרכזי לפרוטוקול האבטחה של שכבת התעבורה TLS המספק שיפורים משמעותיים באבטחה ובביצועים בהשוואה לגרסאות קודמות. ה-JDK תומך כעת בגרסת פרוטוקול זו. החומר מבוסס על מאמר מאת סיימון ריטר ותיעוד רשמי .
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION