18

以下三个功能哪个更高效;

  public String getmConnectedDeviceName1() {
        if(null != mServerDevice) {
            return mServerDevice.getName();
        }
        else {
            return null;
        }
    }

  public String getmConnectedDeviceName2() {
        return mServerDevice == null ? null : mServerDevice.getName();
    }


  public String getmConnectedDeviceName3() {
        try{
            return mServerDevice.getName();
        }
        catch(NullPointerException e) {
            return null;
        }
    }

请以具体可接受的逻辑回复。

4

6 回答 6

29

mServerDevice前者在is时效率更高null。什么时候mServerDevice不是null两者都差不多。比较null只是比较两个 32 位整数,这是非常快速的操作。抛出异常代价高昂,因为应该创建新对象并填充堆栈跟踪。

三元运算符与语句... ? ... : ...一样有效if (...) ... else ...,因为两者都被翻译成相同的字节码。

于 2013-03-02T08:23:11.683 回答
19

好吧,不需要“向后”比较(主要是 C 的保留,如果您使用的是糟糕的编译器或忽略的警告,则可能无法检测到拼写错误) - 条件运算符使事情变得更简单:

return mServerDevice != null ? mServerDevice.getName() : null;

或者:

    return mServerDevice == null ? null : mServerDevice.getName();

这比 catch 更具可读性效率NullPointerException

在更复杂的场景中,只需使用if版本即可。除非你调用一个错误的库,否则你永远不应该抓住它,它会以一种你无法避免的方式抛出它。NullPointerException异常并不意味着以这种方式使用。它们用于检测编程错误和异常的外部条件(例如 IO 故障)。

与其他控制流构造相比,异常相对昂贵。但是,不要在另一个方向上走得太远:有些人即使在应该使用异常时也避免异常,因为他们误入歧途地希望避免它们的成本。如果使用得当,异常不应成为性能配置文件的重要组成部分:如果您发现它们占用了您很多时间,则说明您的环境中存在严重错误(例如,您一直在尝试连接到您无权访问的数据库)或者您正在滥用异常。

于 2013-03-02T08:21:32.537 回答
2

我绝对同意其余的答案。为了不完全一样,我只会告诉你,现在我正在介绍一个已经编写了大约3年的相当大的商业源代码,我还没有看到任何使用try-catch你提到的方法的声明;虽然有很多检查null;)

于 2013-03-02T08:47:51.123 回答
1

使用 try-catch 子句绝对不是更好的方法。

try-catch 也会导致新对象的实例化(异常)。如果 else 也提高了可读性。因此,如果您有很多 n == null 的情况,我会说 (n!=null) 更快。n!=null 也是超快的构造。

于 2013-03-02T08:24:28.070 回答
0

在可以的情况下使用if-else。抛出和捕获异常可能很昂贵,应该用于处理错误情况(不适用于逻辑分支)。

于 2013-03-02T08:24:00.807 回答
0

不管性能如何,我更喜欢 if-else 形式。假设 mServerDevice 不为 null,但在 getName() 调用期间出现严重错误,并引发 NullPointerException。基于异常的版本将静默返回 null,而不记录错误。

于 2013-03-02T08:26:27.550 回答