为什么Sun更喜欢NoSuchMethodError + NullPointerException而不是Class检查?

时间:2015-09-14 09:18:07

标签: java reflection

我做了一个小的调试会话,偶然发现了Sun / Oracle代码中的以下代码片段:

try {
        XmlSchema s = null;
        s.location();
    } catch (NullPointerException e) {
        // as epxected
    } catch (NoSuchMethodError e) {
         // this is not a 2.1 API. Where is it being loaded from?
         ...
    }

我认为这有几个缺点,首先是期待NullPointerException,使用((XmlSchema)null).location();并期待NoSuchMethodError。如果我要进行代码审查,我会通过触发异常作为常规事件将其标记为未占用的代码。

在我看来,使用XmlSchema.getClass().getMethod("location", new Object[0])会有更好的想法。

由于此代码用于官方API实现,我想知道是否存在边缘情况,我不知道哪个防止类检查是一个很好的解决方案,并且必须使用此代码片段作为后退。

更新:

这个问题与"Strange NullPointerException CATCH in OpenJDK JAXB有关,但它没有回答我关于他们为什么这样做的问题。这只是解释为什么他们这样做的原因。

UPDATE2:

使用测试代码:

@Test
public void test() throws NoSuchMethodException, SecurityException {
    Method method = ArrayList.class.getMethod("size");
    if(method == null)
        throw new UnsupportedOperationException();
}

@Test
@SuppressWarnings("null")
public void test2() {
    ArrayList<?> list = null;
    try {
        list.size();
    }
    catch(NullPointerException e) {
    }
    catch(NoSuchMethodError e) {
        throw new UnsupportedOperationException();
    }
}

我发现TestNG报告了两个测试的0(在你预热后)。由于代码是在类的静态方法中执行的,因此该代码最多执行一次。

所以时间不是原因。另一个问题是现代编译器检测到对空引用执行location方法的尝试,因此需要抑制执行。

所以时间不是原因(不再是?)因为喜欢这种黑客而不是适当的班级检查。

有人知道更多答案吗?

1 个答案:

答案 0 :(得分:1)

如果使用catch来处理NoSuchMethodError,则会异常使用慢速代码。如果您使用反射来检查方法的存在,则始终使用慢速代码。