Android Activity与Fragments的接口:try / catch块与instanceof检查

时间:2015-02-17 18:31:14

标签: java android android-fragments

在Google的article on communicating with Fragments中,作者提供了以下检查示例,以确定片段的调用活动是否实现了所需的接口:

try {
    mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
    throw new ClassCastException(activity.toString()
        + " must implement OnHeadlineSelectedListener");
}

通常,我更喜欢使用显式检查来尝试/捕获块。在这种情况下,我认为以下示例更可取:

if (activity instanceof OnHeadlineSelectedListener) {
    mCallback = (OnHeadlineSelectedListener) activity;
} else {
    throw new ClassCastException(activity.toString()
        + " must implement OnHeadlineSelectedListener");
}

是否有理由更喜欢一种检查策略而不是另一种?在定义Fragments接口时是否应该使用另一种策略?

3 个答案:

答案 0 :(得分:2)

  

是否有理由更喜欢一种检查策略而不是另一种?

主要是个人偏好。对于阅读代码的人来说,instanceof更明确。 try{}catch{}在功能上做同样的事情

  

在定义接口时是否应该使用另一种策略    片段?

不是我知道的。

进一步说明:(因为我觉得自己像是漫无目的)

这不应该是一个“意外”的问题。如果编写好代码,就不应该担心错误。(忽略这一点,以回应OP的评论)

另外值得一提的是,Google推荐的抛出新错误的方法会增加不必要的代码,因为默认异常将包含您需要的信息。此外,抛出错误会造成糟糕的用户体验。

任何一个选项的性能影响都可以忽略不计(除非你做了一些不合理的事情,比如循环和检查数千次),所以(性能方面)你可以使用适合你喜欢的编码风格的任何一个。

我的猜测是Google建议使用try{} catch{}选项,因为从catch块中抛出异常比从else抛出异常更有意义。这可能也是因为该文章的作者个人更喜欢try{}catch{}风格。

从功能上讲,两种方法都做同样的事情。 instanceof检查的含义更为明确,因为代码清楚地说明了您要检查的内容,如果必须进行检查则我建议使用instanceof方法。

答案 1 :(得分:0)

通常情况下,我更喜欢使用instanceof方法,因为抛出和捕获异常被认为是昂贵的。 另外,我认为实例方法更具可读性。

答案 2 :(得分:0)

请参阅我之前的两个答案,了解我如何处理这两个问题:

片段(https://stackoverflow.com/a/27716730/950427):

public MyAdapter(Fragment fragment) {
    try {
        this.mAdapterCallback = ((AdapterCallback) fragment);
    } catch (ClassCastException e) {
        throw new ClassCastException("Fragment must implement AdapterCallback.");
    }
}

活动(https://stackoverflow.com/a/27716788/950427):

public MyAdapter(Context context) {
    try {
        this.mAdapterCallback = ((AdapterCallback) context);
    } catch (ClassCastException e) {
        throw new ClassCastException("Activity must implement AdapterCallback.");
    }
}

需要上下文的片段的特例:

private Activity activity;

public MyAdapter(Fragment fragment) {
    this.fragment = fragment.getActivity(); // use as Context
    try {
        this.mAdapterCallback = ((AdapterCallback) fragment);
    } catch (ClassCastException e) {
        throw new ClassCastException("Fragment must implement AdapterCallback.");
    }
}