Java vs Objective C в случае исключения nullpointer

Почему Java часто генерирует исключение null-указателя, если я пытаюсь получить доступ к нулевым значениям, а Objective C – нет?

Ява:

public class SubscribeEmailActivity { String status; public static void main(String[] args){ if(Status.equals(null)||status.equals(""){ // i am getting error here } } } 

Цель C:

 //in .h file NSString *exp; //in .m file if ([exp isEqualToString:NULL] ||[exp isEqualToString:@""]) { // i am not getting any error } 

В конечном счете, единственный способ полностью решить эту проблему – использовать другой язык программирования:

  • В Objective-C вы можете сделать эквивалент вызова метода на nil, и абсолютно ничего не произойдет. Это делает ненужные проверки, но может сделать ошибки намного сложнее для диагностики.
  • В Ницце, языке, основанный на Java, существуют две версии всех типов: потенциально-нулевая версия и непустая версия. Вы можете ссылаться только на методы с непустыми типами. Потенциально-нулевые типы могут быть преобразованы в непустые типы путем явной проверки на null. Это значительно облегчает понимание того, где нужны нулевые проверки, а где нет.

Проблема в вашей оценке в java, это должно быть:

 if(status == null||status.equals("")) { //Do not try to dereference status.... 

Следует отметить, что это работает только потому, что Java и другие языки позволяют сократить логические оценки. В этом случае некоторая простая булева алгебра:

 true || ??? => true 

Как только первый термин оценивается как истинный, мы знаем, что условное условие OR также будет оцениваться как истинное, нет необходимости изучать второй термин.

Кроме того, вы можете использовать Apache Commons isEmpty() или сверните свой собственный:

 public static final boolean isEmpty(String arg0) { if(arg0 == null) return true; if(arg0.trim().length() < 1) return true; return false; } 

Показанная версия сродни isBlank в Apache Commons.

Вероятно, это не ответит на ваш вопрос, но одно правило, чтобы исключить исключение из null-указателя и в то же время избежать нулевой проверки, заключается в том, чтобы инвертировать проверку следующим образом:

 Status status = null; if("".equals(status)){ //.... } 

Который вернет false.

При использовании:

 if(status.equals("")){ } 

Будет выбросить исключение NPE.

В вызовах метода Objective C считается эквивалентным отправке сообщения, а отправка сообщения в nil ничего не делает. Это означает, что вам не нужно записывать нулевые проверки, которые потребуются в Java, что более удобно для программистов, которые могут писать более компактный код.

С другой стороны, он также может быть источником ошибки: если вы ожидали отправить сообщение реальному объекту, но отправите его на nil , в Objective C вы не получите предупреждение. В Java эта операция вызывает NullPointerException , что дает понять, что у вас есть ошибка.

Поскольку разработчики языка должны сделать компромисс между удобством и безопасностью, ни один из вариантов не является объективно лучше. Дизайнеры Objective C решили, что лучше использовать nil как черную дыру: она проглатывает все, что вы бросаете на нее. Дизайнеры Java решили, что лучше иметь дело с null порожденным явной ошибкой. На самом деле ничего более.

Если status переменной null в Java, тогда попытка вызова status.equals() будет генерировать исключение NullPointer. isEqualToString не является функцией-членом строк Objective-C, она просто сравнивает строку и объект.

Речь идет только о том, как был разработан язык. Вы можете посмотреть здесь, если вы достаточно храбры, чтобы увидеть, как работает objc_msgSend и почему вы можете отправлять сообщения нильским объектам.

В вашем коде

if(Status.equals(null)||status.equals("") вы сравниваете String с null (null не является String).

Невозможно сравнить String с не-String. В случае кодирования iOS я считаю, что

[exp isEqualToString:NULL]

Преобразует аргумент в ничто, поскольку нуль или нуль одинаковы, а затем сравнивают его, поэтому он работает.