Для Java-программистов null — это головная боль. Вас часто беспокоят исключения нулевого указателя (NPE). Даже изобретатель Java признал, что это была огромная ошибка с его стороны. Почему Java сохраняет значение null? Значение null существует уже некоторое время, и я думаю, что изобретатели Java знали, что значение null вызывает больше проблем, чем проблем, которые оно решает, но значение null все еще присутствует в Java.
Я удивляюсь все больше и больше, потому что принцип проектирования Java заключается в упрощении вещей, поэтому не тратится время на указатели, перегрузку операторов, а реализация множественного наследования как раз наоборот. Что ж, на самом деле я не знаю ответа на этот вопрос, но я знаю, что как бы ни критиковали null со стороны разработчиков Java и сообщества открытого исходного кода, мы должны сосуществовать с null. Вместо того, чтобы сожалеть о существовании null, нам следует лучше узнать о null и убедиться, что null используется правильно.
Зачем вам нужно изучать null в Java? Потому что, если вы не обратите внимания на null, Java заставит вас страдать от NullPointerException, и вы получите болезненный урок. Энергичное программирование — это искусство, которое ваша команда, клиенты и пользователи оценят больше. По моему опыту, одной из основных причин исключений нулевого указателя является недостаточное знание нуля в Java. Многие из вас уже знакомы с null, но те, кто нет, могут узнать что-то старое и новое о null. Давайте еще раз изучим некоторые важные знания о null в Java.
Что такое Null в Java?
Как я уже сказал, null — очень важное понятие в Java. Первоначальное намерение null — представить что-то отсутствующее, например, отсутствующего пользователя, ресурса или других вещей. Однако год спустя неприятное исключение нулевого указателя вызвало много беспокойства среди Java-программистов. В этом материале мы изучим основные детали ключевого слова null в Java, а также изучим некоторые методы минимизации проверок на null и способы избежать неприятных исключений нулевого указателя.
1) Прежде всего, null — это ключевое слово в Java, такое же как public, static и Final. Он чувствителен к регистру, вы не можете написать null как Null или NULL, компилятор не распознает их и сообщит об ошибке.
Скопируйте код кода следующим образом:
Объект obj = NULL // Не в порядке;
Объект obj1 = ноль // ОК
Эта проблема может возникнуть у программистов, использующих другие языки, но теперь использование IDE сделало эту проблему тривиальной. Теперь, когда вы вводите код, такие IDE, как Eclipse и Netbeans, могут исправить эту ошибку. Но при использовании других инструментов, таких как блокнот, Vim и Emacs, эта проблема будет пустой тратой вашего драгоценного времени.
2) Точно так же, как каждый примитивный тип имеет значение по умолчанию, например, значение по умолчанию для int равно 0, значение по умолчанию для логического значения равно false, а значение null является значением по умолчанию для любого ссылочного типа. Строго говоря, это значение по умолчанию. всех типов объектов. Точно так же, как вы создаете логическую переменную со значением по умолчанию false, любая ссылочная переменная в Java имеет значение по умолчанию null. Это справедливо для всех переменных, таких как переменные-члены, локальные переменные, переменные экземпляра, статические переменные (но когда вы используете неинициализированную локальную переменную, компилятор предупредит вас). Чтобы продемонстрировать этот факт, вы можете наблюдать за этой ссылочной переменной, создав переменную и затем распечатав ее значение, как показано в следующем коде:
Скопируйте код кода следующим образом:
частный статический объект myObj;
public static void main(String args[]){
System.out.println("Каково значение myObjc: " + myObj);
}
Каково значение myObjc: null
Это справедливо как для статических, так и для нестатических объектов. Как вы можете видеть здесь, я определил myObj как статическую ссылку, поэтому могу использовать ее непосредственно в основном методе. Обратите внимание, что основной метод является статическим и не может использовать нестатические переменные.
3) Мы хотим прояснить некоторые недоразумения. Null не является ни объектом, ни типом. Вы можете присвоить его любому ссылочному типу. См. код ниже.
Скопируйте код кода следующим образом:
String str = null // строке может быть присвоено значение null;
Integer itr = null // вы также можете присвоить значение NULL Integer.
Double dbl = null // null также может быть присвоен Double
String myStr = (String) null // значение null можно привести к типу String;
Integer myItr = (Integer) null // его также можно привести к типу Integer;
Double myDbl = (Double) null // да, это возможно, ошибок нет;
Вы можете видеть, что приведение значения null к любому ссылочному типу возможно во время компиляции и выполнения и не вызывает исключения нулевого указателя во время выполнения.
4) Ссылочным переменным можно присвоить значение NULL, но нельзя присвоить значение NULL переменным базового типа, таким как int, double, float и boolean. Если вы это сделаете, компилятор выдаст такую ошибку:
Скопируйте код кода следующим образом:
int i = null // несоответствие типов: невозможно преобразовать значение null в int
short s = null // несоответствие типов: невозможно преобразовать из null в short;
byte b = null: // несоответствие типов: невозможно преобразовать нуль в байт
double d = null // несоответствие типов: невозможно преобразовать значение null в double
Целое число itr = null // это нормально;
int j = itr // это тоже нормально, но NullPointerException во время выполнения
Как видите, когда вы присваиваете значение null непосредственно примитивному типу, возникает ошибка компиляции. Но если вы присвоите null объекту класса-оболочки, а затем присвоите объект соответствующим базовым типам, компилятор не сообщит об этом, но вы столкнетесь с исключением нулевого указателя во время выполнения. Это вызвано автоматической распаковкой в Java, которую мы увидим в следующем пункте.
5) Любой класс-оболочка, содержащий нулевое значение, выдаст исключение нулевого указателя, когда Java распаковывает и генерирует базовые типы данных. Некоторые программисты ошибаются, полагая, что автобокс преобразует значение null в значение по умолчанию соответствующего базового типа, например 0 для int и false для логического типа, но это неверно, как показано ниже:
Скопируйте код кода следующим образом:
Целое число iAmNull = ноль;
int i = iAmNull // Помните: нет ошибки компиляции;
Но когда вы запустите приведенный выше фрагмент кода, вы увидите на консоли, что основной поток выдает исключение нулевого указателя. Многие такие ошибки возникают при использовании значений ключей HashMap и Integer. Ошибка появится при запуске следующего кода.
Скопируйте код кода следующим образом:
импортировать java.util.HashMap;
импортировать java.util.Map;
/**
* Пример автобокса и NullPointerExcpetion.
*
* @автор WINDOWS 8
*/
тест публичного класса {
public static void main(String args[]) выдает InterruptedException {
Номер картыAndCount = новый HashMap<>();
числа int[] = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
for(int i: числа){
int count = NumberAndCount.get(i);
numberAndCount.put(i, count++ // здесь исключение NullPointerException);
}
}
}
Выход:
Скопируйте код кода следующим образом:
Исключение в потоке «основной» java.lang.NullPointerException
в Test.main(Test.java:25)
Этот код выглядит очень просто и без ошибок. Все, что вам нужно сделать, это узнать, сколько раз число появляется в массиве, что является типичным методом поиска дубликатов в массивах Java. Разработчик сначала получает предыдущее значение, затем добавляет его и, наконец, помещает значение обратно в карту. Программист может подумать, что при вызове метода put автоматическая упаковка будет обрабатывать упаковку int в Interger, но он забывает, что когда число не имеет значения счетчика, метод get() HashMap вернет ноль, а не 0. , поскольку значение Integer по умолчанию равно нулю, а не 0. Автобокс вернет исключение NullPointerException при передаче нулевого значения в переменную int. Представьте, если бы этот код находился внутри гнезда if и не запускался в среде контроля качества, но как только вы поместите его в производственную среду, БУМ :-)
6) Если используется переменная ссылочного типа со значением null, операция instanceof вернет false:
Скопируйте код кода следующим образом:
Целое число iAmNull = ноль;
если (iAmNull экземпляр целого числа) {
System.out.println("iAmNull — это экземпляр Integer");
}еще{
System.out.println("iAmNull НЕ является экземпляром Integer");
}
Выход:
Скопируйте код кода следующим образом:
я
AmNull НЕ является экземпляром Integer.
Это очень важная особенность операции instanceof, делающая ее полезной для проверок приведения типов.
7) Возможно, вы знаете, что нельзя вызвать нестатический метод для использования переменной ссылочного типа с нулевым значением. Он выдаст исключение нулевого указателя, но вы можете не знать, что можно использовать статические методы для использования переменной ссылочного типа со значением null. Поскольку статические методы используют статическую привязку, исключения нулевого указателя не будут создаваться. Вот пример:
Скопируйте код кода следующим образом:
Тестирование публичного класса {
public static void main(String args[]){
Тестирование myObject = null;
мойОбъект.iAmStaticMethod();
мойОбъект.iAmNonStaticMethod();
}
частная статическая сила iAmStaticMethod(){
System.out.println("Я статический метод, может быть вызван по нулевой ссылке");
}
частная пустота iAmNonStaticMethod(){
System.out.println("Я НЕ статический метод, не звоните мне по нулю");
}
Выход:
Скопируйте код кода следующим образом:
Я статический метод, его можно вызвать по нулевой ссылке.
Исключение в потоке «основной» java.lang.NullPointerException
в Testing.main(Testing.java:11)
8) Вы можете передать методу значение null, и метод может получить любой ссылочный тип. Например, public void print(Object obj) может вызвать print(null) вот так. Это нормально с точки зрения компиляции, но результат полностью зависит от метода. Null-безопасные методы, такие как метод print в этом примере, не создают исключение NullPointerException и просто корректно завершают работу. Если бизнес-логика это позволяет, рекомендуется использовать нулевые методы.
9) Вы можете использовать операции == или != для сравнения нулевых значений, но вы не можете использовать другие алгоритмы или логические операции, такие как «меньше» или «больше». В отличие от SQL, null==null вернет true в Java, как показано ниже:
Скопируйте код кода следующим образом:
тест публичного класса {
public static void main(String args[]) выдает InterruptedException {
Строка abc = ноль;
Строка cde = ноль;
если (abc == cde) {
System.out.println("null == null истинно в Java");
}
если (ноль! = ноль) {
System.out.println("null != null в Java является ложным");
}
// классическая проверка на ноль
если (abc == ноль) {
// сделать что-то
}
// не ок, ошибка времени компиляции
если (abc > ноль) {
}
}
}
Выход:
Скопируйте код кода следующим образом:
null == null истинно в Java
В Java все дело в нуле. Имея некоторый опыт программирования на Java и используя простые приемы, позволяющие избежать исключений нулевых указателей, вы можете сделать свой код нулевым. Поскольку значение null часто используется как пустое или неинициализированное значение, это является источником путаницы. Для методов также очень важно записывать, как ведет себя метод, когда в качестве параметра используется значение null. В общем, помните, что null является значением по умолчанию для любой переменной ссылочного типа. Вы не можете использовать нулевые ссылки для вызова каких-либо методов экземпляра или переменных экземпляра в Java.