JavaRush /جاوا بلاگ /Random-UR /9 вещей о NULL в Java
Sdu
سطح

9 вещей о NULL в Java

گروپ میں شائع ہوا۔
Java и null неразрывно связаны. Едва ли существует Java-программист, не встречавшийся с "null pointer exception" и это печальный факт. Даже изобретатель концепции "null" назвал ее своей ошибкой на миллиард долларов, тогда зачем Java поддерживает ее? null был здесь долгое время, и я полагаю, создатели Java знают, что он создает больше проблем чем решает, так почему же они все еще мирятся с этим. И это удивляет меня еще больше, потому что философией Java было упростить вещи, вот почему они больше не возятся с указателями, перегрузкой операторов и множественным наследованием, но почему null?9 вещей о NULL в Java - 1Ну, я действительно не знаю ответ на этот вопрос, но, что я точно знаю, не имеет значения сколько бы null критиковался Java-программистами и open-source сообществом, мы должны жить с ним. Вместо того чтобы сожалеть, лучше узнать больше и быть уверенным что мы используем null правильно.

Почему Вы должны узнать о null в Java?

Потому что, если Вы не обратите внимания на null, будьте уверены, Java заставит страдать от ужасного java.lang.NullPointerException и Вы выучите этот урок, но пойдете более трудным путем. Написание устойчивого к "падениям" codeа - это искусство и Ваша команда, заказчики и пользователи оценят это. По моему опыту, одна из основных причин NullPointerException это недостаток знаний о null в Java. Многие из Вас уже знакомы с null, остальные смогу узнать некоторые старые и новые вещи о ключевом слове null. Давайте повторим or узнаем некоторые важные вещи о null в Java.

What есть null в Java

Как я говорил, null очень-очень важная концепция в Java. Первоначально он был изобретен для обозначения отсутствия чего-либо, например, отсутствие пользователя, ресурса or чего угодно, но уже в течение года озадачил Java-программистов множеством null pointer exception. В этом уроке, мы узнаем основные факты о ключевом слове null в Java, изучим некоторые приемы How избежать неприятностей с null pointer exceptions и минимизировать проверки на null.
  1. Перво-наперво, null это ключевое слово в Java, так же How public, static or final. Регистр учитывается, Вы не можете писать null How Null or NULL, компилятор не распознает его и будет выброшена ошибка.

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

    Зачастую, с этим встречаются программисты, перешедшие с других языков программирования, но при использовании современных IDE проблема становится незначительной. В наши дни, IDE вроде Eclipse or NetBeans могут исправлять эту ошибку пока Вы набираете code, но в эпоху 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)

    Этот code выглядит очень простым и безобидным. Вы просто подсчитываете сколько раз число встречается в массиве, классическая техника нахождения дубликатов. Разработчик берет предыдущее подсчитанное количество, увеличивает его на единицу и вставляет обратно в Map. Он мог бы подумать, что авто-упаковка позаботится о преобразовании Integer в int, How это делается в момент вызова метода put(), но он забывает, что если для числа подсчет еще не проводился, метод get() вернет из HashMap null, не ноль, потому что meaning по умолчанию для Integer это null, а не 0, и авто-упаковка выбросит null pointer exception при попытке сконвертировать Integer в переменную int.

  6. Оператор instanceof будет возвращать false если в качестве параметра указать любую ссылочную переменную со meaningм null or 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. Вы знаете, что Вы не можете вызвать нестатический метод у ссылочной переменной со meaningм null, это вызовет NullPointerException, но Вы можете не знать, что Вы можете вызвать статический метода у ссылочной переменной со meaningм 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)

    может быть вызван How

    
    print(null)

    Это нормально с точки зрения компилятора, но дальнейшее поведение fully зависит от метода. Null-безопасный метод не выбросит NullPointerException, а просто корректно завершится. Если бизнес логика позволяет, рекомендуется писать null-безопасные методы.

  9. Вы можете сравнивать null используя операторы == (равно) и != (не равно), но не можете использовать его с другими арифметическими or логическими операторами, вроде < (меньше) or > (больше). В отличии от SQL, в Java null == null вернет true, How показано ниже:

    
    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. Наработав некоторый опыт в Java-программировании и используя простые уловки, чтобы избежать NullPointerException, Вы сможете сделать Ваш code безопасным. Т.к. meaning null может рассматриваться How пустое or неинициализированное meaning, это часто является источником путаницы, вот почему так важно documentировать поведение метода при входящем значении null. Всегда помните, null это meaning по умолчанию ссылочных переменных, и Вы не можете вызывать методы экземпляра or получать доступ к переменным экземпляра используя null-ссылку в Java.
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION