6

如果我尝试访问空值,而 Objective C 没有,为什么 Java 经常抛出空指针异常?

爪哇:

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
}
4

7 回答 7

7

问题出在你在java中的评估中,它应该是:

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

应该注意的是,这只适用于 Java 和其他语言,允许在逻辑评估中使用捷径。在这种情况下一些简单的布尔代数:

true || ??? => true

一旦第一项评估为真,我们知道 OR 条件也将评估为真,无需检查第二项。

此外,您可以使用 Apache CommonsisEmpty()或自行开发:

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

显示的版本类似于isBlankApache Commons 中的版本。

于 2013-08-08T13:39:01.150 回答
6

最终,完全解决这个问题的唯一方法是使用不同的编程语言:

  • 在 Objective-C 中,您可以执行相当于在 nil 上调用方法的操作,并且绝对不会发生任何事情。这使得大多数空检查变得不必要,但会使错误更难诊断。
  • 在 Java 派生语言 Nice 中,所有类型都有两个版本:潜在空版本和非空版本。您只能在非空类型上调用方法。通过显式检查 null 可以将可能为 null 的类型转换为非 null 类型。这使得更容易知道哪些地方需要空检查,哪些地方不需要。
于 2013-08-08T13:41:26.210 回答
4

这可能不会回答您的问题,但是避免空指针异常并同时避免空检查的一条规则是像这样反转检查:

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

这将返回错误。

使用时:

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

将抛出 NPE 异常。

于 2013-08-08T13:43:14.893 回答
4

在Objective C中,方法调用被认为等同于发送消息,而发送消息nil什么也不做。这意味着您不必编写 Java 所需的空值检查,这对于可以编写更紧凑代码的程序员来说更方便。

另一方面,它也可能是错误的来源:如果您希望将消息发送到真实对象但将其发送到nil,那么在 Objective C 中您将不会收到警告。在 Java 中,此操作会导致 aNullPointerException被抛出,从而清楚地表明您有一个错误。

由于语言设计者必须在便利性和安全性之间做出权衡,客观上这两种选择都不是更好的选择。Objective C 的设计者决定最好实现nil为一个黑洞:它会吞下你扔给它的任何东西。Java 的设计者认为,如果处理null生成显式错误会更好。真的没什么。

于 2013-08-08T13:48:54.837 回答
2

如果变量statusnullJava 中,则尝试调用status.equals()将引发 NullPointer 异常。isEqualToString不是 Objective-C 字符串的成员函数,它只是比较一个字符串和一个对象。

于 2013-08-08T13:40:04.610 回答
2

这只是语言如何设计的问题。如果你足够勇敢,你可以看看这里,看看 objc_msgSend 是如何工作的,以及为什么你可以向 nil 对象发送消息。

于 2013-08-08T13:44:37.413 回答
2

在您的代码中

if(Status.equals(null)||status.equals("")您正在将字符串与null(null 不是字符串)进行比较。

无法将字符串与非字符串进行比较。在 iOS 编码的情况下,我相信

[exp isEqualToString:NULL]

将参数转换为空,因为 null 或 nil 相同,然后比较它,因此它有效。

于 2013-08-08T13:49:14.527 回答