תכונות חדשות ב- Java 8

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

במאמר זה נבחן במהירות כמה מהתכונות החדשות המעניינות ביותר ב- Java 8.

נדבר על: ממשק ברירת מחדל ושיטות סטטיות, הפניה לשיטה ואופציונלי.

כבר כיסינו כמה מהתכונות של מהדורת ה- Java 8 - ממשק API של זרם, ביטויים למבדה וממשקים פונקציונליים - מכיוון שהם נושאים מקיפים שראויים למבט נפרד.

2. ממשק ברירת מחדל ושיטות סטטיות

לפני Java 8, לממשקים יכולות להיות רק שיטות מופשטות ציבוריות. לא ניתן היה להוסיף פונקציונליות חדשה לממשק הקיים מבלי לאלץ את כל כיתות היישום ליצור יישום של השיטות החדשות, ולא ניתן היה ליצור שיטות ממשק עם יישום.

החל ב- Java 8, ממשקים יכולים להיות סטָטִי ו בְּרִירַת מֶחדָל שיטות שלמרות שהוכרזו בממשק, יש להן התנהגות מוגדרת.

2.1. שיטה סטטית

שקול את השיטה הבאה של הממשק (נקרא לממשק זה רכב):

מפיק מחרוזת סטטי () {להחזיר "רכבי N&F"; }

הסטטי יַצרָן() השיטה זמינה רק דרך ממשק ובפנים. לא ניתן לעקוף את זה על ידי כיתה מיישמת.

כדי לקרוא לזה מחוץ לממשק יש להשתמש בגישה הסטנדרטית לשיחת שיטה סטטית:

מפיק מיתרים = רכב.מפיק ();

2.2. שיטת ברירת מחדל

שיטות ברירת מחדל מוכרזות באמצעות החדש בְּרִירַת מֶחדָל מילת מפתח. אלה נגישים באמצעות מופע המחלקה המיישמת וניתן לעקוף אותם.

בואו נוסיף a בְּרִירַת מֶחדָל שיטה שלנו רכב ממשק, אשר יתקשר גם אל סטָטִי שיטה של ​​ממשק זה:

ברירת מחדל מחרוזת getOverview () {להחזיר "טרקטורון מתוצרת" + מפיק (); }

נניח שממשק זה מיושם על ידי הכיתה VehicleImpl. לביצוע ה- בְּרִירַת מֶחדָל יש ליצור מופע של מחלקה זו:

רכב רכב = VehicleImpl חדש (); סקירה כללית על מחרוזות = vehicle.getOverview ();

3. הפניות לשיטה

ניתן להשתמש בהפניה לשיטה כאלטרנטיבה קצרה וקריאה יותר לביטוי למבדה המכנה רק שיטה קיימת. ישנן ארבע גרסאות של הפניות לשיטה.

3.1. התייחסות לשיטה סטטית

ההתייחסות לשיטה סטטית מכילה את התחביר הבא: ContainingClass :: methodName.

בואו ננסה לספור את כל המיתרים הריקים בתא רשימה בעזרת Stream API.

isReal בוליאני = list.stream (). anyMatch (u -> User.isRealUser (u));

התבונן מקרוב בביטוי למבדה ב anyMatch () שיטה, זה פשוט קורא לשיטה סטטית isRealUser (משתמש משתמש) של ה מִשׁתַמֵשׁ מעמד. אז ניתן להחליף אותו בהתייחסות לשיטה סטטית:

isReal בוליאני = list.stream (). anyMatch (משתמש :: isRealUser);

סוג זה של קוד נראה הרבה יותר אינפורמטיבי.

3.2. התייחסות לשיטת מופע

ההתייחסות לשיטת מופע מכילה את התחביר הבא: גontainingInstance :: methodName. בעקבות שיטת שיחות קוד isLegalName (מחרוזת מחרוזת) מהסוג מִשׁתַמֵשׁ המאמת פרמטר קלט:

משתמש משתמש = משתמש חדש (); בוליאני isLegalName = list.stream (). anyMatch (משתמש :: isLegalName); 

3.3. התייחסות לשיטת מופע של אובייקט מסוג מיוחד

שיטת התייחסות זו נוקטת בתחביר הבא: גontainingType :: methodName. דוגמה::

ספירה ארוכה = list.stream (). filter (String :: isEmpty) .count ();

3.4. התייחסות לבנאי

התייחסות לבנאי לוקחת את התחביר הבא: ClassName::חָדָשׁ. מכיוון שבונה בג'אווה הוא שיטה מיוחדת, ניתן להחיל עליו גם הפניה לשיטה בעזרת חָדָשׁכשם שיטה.

זרם זרם = list.stream (). מפה (משתמש :: חדש);

4. אופציונאלי

לפני שמפתחי Java 8 נאלצו לאמת בקפידה ערכים שהם התייחסו אליהם בגלל אפשרות לזרוק את NullPointerException (NPE). כל הבדיקות הללו דרשו קוד דיודה מעצבן ומועד לטעויות.

ג'אווה 8 אופציונאלי השיעור יכול לסייע בהתמודדות עם מצבים שיש אפשרות להשיג את NPE. זה עובד כמכולה לאובייקט מהסוג ט. הוא יכול להחזיר ערך של אובייקט זה אם ערך זה אינו a ריק. כאשר הערך בתוך מיכל זה הוא ריק זה מאפשר לעשות כמה פעולות שהוגדרו מראש במקום לזרוק NPE.

4.1. יצירת ה אופציונאלי

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

אופציונלי אופציונלי = Optional.empty ();

מחזיר ריק אופציונאלי.

מחרוזת str = "value"; אופציונלי אופציונלי = Optional.of (str);

מחזירה אופציונאלי שמכיל ערך שאינו אפס.

אופציונלי אופציונלי = Optional.ofNullable (getString ());

יחזיר an אופציונאלי עם ערך ספציפי או ריק אופציונאלי אם הפרמטר הוא ריק.

4.2. שימוש אופציונלי

לדוגמה, אתה מצפה לקבל רשימה ובמקרה של ריק אתה רוצה להחליף אותו במופע חדש של רשימת מערך. Wעם הקוד שלפני Java 8 אתה צריך לעשות משהו כזה:

רשימת רשימה = getList (); List listOpt = list! = Null? רשימה: ArrayList חדש ();

עם Java 8 ניתן להשיג את אותה פונקציונליות עם קוד קצר בהרבה:

רשימה listOpt = getList (). OrElseGet (() -> ArrayList חדש ());

יש עוד קוד boilerplate כשאתה צריך להגיע לשדה של אובייקט כלשהו בדרך הישנה. נניח שיש לך אובייקט מסוג מִשׁתַמֵשׁ שיש לו שדה מסוג כתובת עם שדה sשלישייה מהסוג חוּט. ומשום מה אתה צריך להחזיר ערך של רְחוֹב שדה אם ישנם קיים או ערך ברירת מחדל אם רְחוֹב הוא ריק:

משתמש משתמש = getUser (); אם (משתמש! = null) {כתובת כתובת = user.getAddress (); אם (כתובת! = null) {String street = address.getStreet (); אם (רחוב! = null) {רחוב חוזר; }}} להחזיר "לא צוין";

ניתן לפשט זאת באמצעות אופציונאלי:

משתמש אופציונלי = Optional.ofNullable (getUser ()); מחרוזת תוצאה = משתמש .map (משתמש :: getAddress) .map (כתובת :: getStreet) .orElse ("לא צוין");

בדוגמה זו השתמשנו ב- מַפָּה() שיטה להמיר תוצאות של קריאה ל- getAdress () אל ה אופציונאלי ו getStreet () ל אופציונאלי. אם אחת משיטות אלה חזרה ריק ה מַפָּה() השיטה תחזיר ריק אופציונאלי.

תאר לעצמך שהגטרים שלנו חוזרים אופציונאלי. אז עלינו להשתמש ב- flatMap () שיטה במקום מַפָּה():

Optional OptionUser = Optional.ofNullable (getOptionalUser ()); תוצאת מחרוזת = optionalUser .flatMap (OptionalUser :: getAddress) .flatMap (OptionalAddress :: getStreet) .orElse ("לא צוין");

מקרה שימוש נוסף של אופציונאלי משתנה NPE למעט חריג אחר. אז כמו שעשינו בעבר, בואו ננסה לעשות זאת בסגנון שלפני Java 8:

ערך מחרוזת = null; תוצאת מחרוזת = ""; נסה {result = value.toUpperCase (); } לתפוס (NullPointerException יוצא מן הכלל) {לזרוק CustomException חדש (); }

ומה אם נשתמש אופציונאלי? התשובה קריאה ופשוטה יותר:

ערך מחרוזת = null; Optional valueOpt = Optional.ofNullable (value); תוצאת מחרוזת = valueOpt.orElseThrow (CustomException :: חדש) .toUpperCase ();

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

5. מסקנה

במאמר זה נדון בקצרה בכמה תכונות חדשות מעניינות ב- Java 8.

יש כמובן תוספות ושיפורים רבים אחרים המפוזרים על פני חבילות ושיעורי Java 8 JDK רבים.

אך המידע המתואר במאמר זה מהווה נקודת התחלה טובה לחקר ולמידה על כמה מהתכונות החדשות הללו.

לבסוף, כל קוד המקור של המאמר זמין ב- GitHub.