JavaRush /בלוג Java /Random-HE /9 דברים על NULL ב-Java
Sdu
רָמָה

9 דברים על NULL ב-Java

פורסם בקבוצה
Java ו- null הולכים יד ביד. אין כמעט מתכנת ג'אווה שלא נתקל ב"חריג מצביע null " וזו עובדה עצובה. אפילו ממציא המושג "ריק" קרא לזה את טעותו של מיליארד הדולר, אז למה ג'אווה תומכת בזה? null נמצא כאן כבר הרבה זמן, ואני מניח שיוצרי Java יודעים שזה יוצר יותר בעיות ממה שהוא פותר, אז למה הם עדיין משלימים עם זה. וזה מפתיע אותי עוד יותר כי הפילוסופיה של ג'אווה הייתה לפשט דברים, וזו הסיבה שהם כבר לא מתעסקים עם מצביעים, עומס יתר של מפעילים וירושה מרובה, אבל למה null? 9 דברים על NULL ב-Java - 1ובכן, אני לא ממש יודע את התשובה לשאלה הזו, אבל מה שאני כן יודע זה שלא משנה כמה ה-null יזכה לביקורת מצד מתכנתי Java וקהילת הקוד הפתוח, אנחנו צריכים לחיות עם זה. במקום להתחרט, עדיף ללמוד עוד ולהיות בטוחים שאנו משתמשים ב-null בצורה נכונה.

למה כדאי ללמוד על null ב-Java?

כי אם לא תשימו לב ל-null, אתם יכולים להיות בטוחים שג'אווה תגרום לכם לסבול בצורה נוראית java.lang.NullPointerExceptionותלמדו את הלקח, אבל תלכו בדרך הקשה. כתיבת קוד עמיד בפני קריסה היא אומנות והצוות, הלקוחות והמשתמשים שלך יעריכו זאת. מניסיוני, אחת הסיבות העיקריות NullPointerExceptionהיא חוסר ידע על null ב-Java. רבים מכם כבר מכירים את null, כל השאר תוכלו ללמוד כמה דברים ישנים וחדשים על מילת המפתח null. בואו נסקור או נלמד כמה דברים חשובים על null ב-Java.

מה זה null ב-Java

כפי שאמרתי, null הוא מושג מאוד מאוד חשוב בג'אווה. זה הומצא במקור כדי לציין היעדר של משהו, כגון היעדר משתמש, משאב או כל דבר אחר, אבל תמה מתכנתי Java עם הרבה null pointer exception. במדריך זה, נלמד את העובדות הבסיסיות על מילת המפתח null ב-Java, ונלמד כמה טריקים כדי למנוע בעיות עם null pointer exceptionsולמזער בדיקות null.
  1. דבר ראשון, null היא מילת מפתח ב-Java, בדיוק כמו public, staticאו final. רישיות רגישות, אתה לא יכול לכתוב null בתור Null או NULL, המהדר לא יזהה אותו ותיזרק שגיאה.

    Object obj = NULL; // Not Ok
    Object obj1 = null //Ok

    לעתים קרובות נתקלים בכך מתכנתים שעברו משפות תכנות אחרות, אך כאשר משתמשים ב-IDE מודרניים, הבעיה הופכת להיות חסרת חשיבות. בימים אלה, IDEs כמו Eclipse או NetBeans יכולים לתקן את השגיאה הזו בזמן שאתה מקליד, אבל בעידן של Notepad, Vim ו-Emacs, זו הייתה בעיה נפוצה שעלולה לגזול הרבה זמן יקר.

  2. Так же, How каждый примитив имеет meaning по умолчанию, например, у int это 0, у boolean это false, null это meaning по умолчанию любых ссылочных типов, проще говоря, для всех an objectов. Так же, How при создании логической переменной ее meaning по умолчанию равно false, так и любые ссылочные переменные в Java по умолчанию будут равны null. Это истинно для всех типов переменных: переменной-члена or локальной переменной, переменной экземпляра or статической переменной, кроме того, компилятор будет ругаться, если Вы используете локальную переменную не проинициализировав ее.

    private static Object myObj;
    public static void main(String args[]){
        System.out.println("What is value of myObjc : " + myObj);
    }
    What is value of myObjc : null

    Это истинно How для статических, так и для не статических an objectов, How Вы можете видеть здесь, я сделал myObj статической ссылкой, так что я могу использовать ее непосредственно в методе main, который является статическим методом и не позволяет обращаться к не статическим переменным изнутри.

  3. Несмотря на распространенное заблуждение, null это не an object (Object) и ни тип. Это просто специальное meaning, которое может быть назначено любому ссылочному типу, и Вы можете привести null к любому типу, How показано ниже:

    String str = null; // null can be assigned to String
    Integer itr = null; // you can assign null to Integer also
    Double dbl = null; // null can also be assigned to Double
    String myStr = (String) null; // null can be type cast to String
    Integer myItr = (Integer) null; // it can also be type casted to Integer
    Double myDbl = (Double) null; // yes it's possible, no error

    Как Вы можете видеть, приведение null к любому ссылочному типу пройдет успешно How во время компиляции, так и во время выполнения программы. В отличии от того, что многие из Вас возможно подумали, это не приведет к выбрасыванию NullPointerException.

  4. null может быть назначен только ссылочному типу, Вы не можете назначить null примитивной переменной вроде int, double, float or boolean. Компилятор выразит Вам свое недовольство если Вы сделаете How показано ниже:

    int i = null; // type mismatch : cannot convert from null to int
    short s = null; // type mismatch : cannot convert from null to short
    byte b = null: // type mismatch : cannot convert from null to byte
    double d = null; //type mismatch : cannot convert from null to double
    
    Integer itr = null; // this is ok
    int j = itr; // this is also ok, but NullPointerException at runtime

    Как Вы можете видеть, когда мы непосредственно присваиваем null примитиву, то получаем ошибку процесса компиляции, но, если присвоить null an objectу класса-обертки, а затем присвоить этот an object соответствующему примитивному типу, компилятор не отреагирует, но мы будем вознаграждены null pointer exception во время выполнения. Это происходит из-за авто упаковки (autoboxing) в Java, и мы еще встретимся с ним в следующем пункте.

  5. Любой класс-обертка со meaningм null будет выбрасывать java.lang.NullPointerException когда Java распакует(unbox) его в примитивную переменную. Некоторые программисты делают ошибку допуская, что авто упаковка(autoboxing) позаботится о конвертации null в meaning по умолчанию для соответствующего примитивного типа, например, 0 для int, false для boolean и т.д., но это не верно, в чем можно убедиться ниже:

    Integer iAmNull = null;
    int i = iAmNull; // Remember - No Compilation Error

    Но, когда Вы запустите данный фрагмент codeа, в консоли Вы увидите

    Exception in thread "main" java.lang.NullPointerException

    Это часто происходит при работе с HashMap и Integer key. Выполнение codeа, показанного ниже прервется, How только Вы его запустите.

    import java.util.HashMap;
    import java.util.Map;
    /**
    * An example of Autoboxing and NullPointerExcpetion
    *
    * @author WINDOWS 8
    */
    public class Test {
        public static void main(String args[]) throws InterruptedException {
            Map numberAndCount = new HashMap<>();
            int[] numbers = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
            for(int i : numbers){
                int count = numberAndCount.get(i);
                numberAndCount.put(i, count++); // NullPointerException here
            }
        }
    }

    Output: Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:25)

    הקוד הזה נראה מאוד פשוט ולא מזיק. אתה פשוט סופר כמה פעמים מספר מופיע במערך, טכניקה קלאסית למציאת כפילויות. המפתח לוקח את הכמות הקודמת שנספרה, מגדיל אותה באחד ומכניס אותה חזרה ל Map. הוא עשוי לחשוב ש-auto-boxing ידאג להמרה Integerל- int, כפי שהוא עושה כאשר השיטה נקראת put(), אבל הוא שוכח שאם המספר עדיין לא נספר, השיטה get()תחזיר HashMapnull, לא אפס, כי ערך ברירת המחדל הוא מספר שלם זהו null, לא 0, והאגרוף האוטומטי יזרוק null pointer exceptionכאשר מנסים להמיר מספר שלם למשתנה int.

  6. האופרטור instanceofיחזיר false אם משתנה התייחסות כלשהו עם הערך null או null עצמו מצוין כפרמטר. דוגמא:

    Integer iAmNull = null;
    if(iAmNull instanceof Integer){
        System.out.println("iAmNull is instance of Integer");
    }else{
        System.out.println("iAmNull is NOT an instance of Integer");
    }

    Output : iAmNull is NOT an instance of Integer

    זהו מאפיין חשוב של המפעיל instanceofשהופך אותו לשימושי לבדיקת סוגים של יציקות.

  7. אתה יודע שאתה לא יכול לקרוא למתודה לא סטטית על משתנה התייחסות null, זה יקרא NullPointerException, אבל אולי אתה לא יודע שאתה יכול לקרוא לשיטה סטטית על משתנה התייחסות null. כי שיטות סטטיות משתמשות בכריכה סטטית, הן לא זורקות NullPointerException. הנה דוגמה:

    public class Testing {
        public static void main(String args[]){
            Testing myObject = null;
            myObject.iAmStaticMethod();
            myObject.iAmNonStaticMethod();
        }
        private static void iAmStaticMethod(){
            System.out.println("I am static method, can be called by null reference");
        }
        private void iAmNonStaticMethod(){
            System.out.println("I am NON static method, don't date to call me by null");
        }
    }

    Output: I am static method, can be called by null reference
    Exception in thread "main" java.lang.NullPointerException
    at Testing.main(Testing.java:11)
  8. אתה יכול להעביר את null כפרמטר לשיטה שמקבלת כל סוג הפניה, למשל:

    public void print(Object obj)

    יכול להיקרא כמו

    print(null)

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

  9. אתה יכול להשוות null באמצעות האופרטורים ==(שווה) ו- !=(לא שווה), אך אינך יכול להשתמש בו עם אופרטורים אריתמטיים או לוגיים אחרים כמו <(פחות מ) או >(גדול מ). שלא כמו SQL, Java null == nullתחזיר true כפי שמוצג להלן:

    public class Test {
    	public static void main(String args[]) throws InterruptedException {
    		String abc = null;
    		String cde = null;
    		if(abc == cde){
    			System.out.println("null == null is true in Java");
    		}
    		if(null != null){
    			System.out.println("null != null is false in Java");
    		}
    		// classical null check
    		if(abc == null){
    			// do something
    		}
    		// not ok, compile time error
    		if(abc > null){
    
    		}
    	}
    }

    Output:
    null == null is true in Java
זה הכל על null ב-Java. על ידי צבירת ניסיון בתכנות ג'אווה ושימוש בטריקים פשוטים להימנעות NullPointerException, תוכל להפוך את הקוד שלך לבטוח. כי ניתן להתייחס ל-null כערך ריק או לא מאותחל, זה לרוב מקור לבלבול, ולכן חשוב לתעד את ההתנהגות של שיטה כאשר ערך null מוזן. זכור תמיד, null הוא ערך ברירת המחדל של משתני התייחסות, ולא תוכל לקרוא לשיטות מופע או לגשת למשתני מופע באמצעות הפניה null ב-Java.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION