2015-09-14 39 views
0

我做了一个小的调试会话,并绊倒了在太阳/ Oracle的代码下面的代码片段:为什么Sun更喜欢NoSuchMethodError + NullPointerException而不是Class检查?

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,使用和期待NoSuchMethodError几个缺点。如果我要进行代码审查,我会通过触发异常作为常规事件将其标记为不可用代码。

在我看来,使用XmlSchema.getClass().getMethod("location", new Object[0])会是一个更好的主意。

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

UPDATE:

这个问题是关系到"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这两个测试(你热身之后)。由于代码是在类的静态方法内执行的,因此该代码最多只能执行一次。

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

因此,时机不是原因(再也不?),而不是适当的班级检查。

有没有人知道更多的答案?

+0

您在哪个特定的类中找到此代码?哪个版本? – Tunaki

+0

这是一个JaxB类。 –

回答

1

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

+0

我测试了时间和时间是相同的0秒。由于此方法在静态方法中执行一次,这可能是15年前的原因,但不再有效。 –

0

看起来,代码片段现在被称为旧的遗留代码,在此期间从未被维护。特别是如果有人注意到任何现代IDE将此代码片段标记为访问NULL引用。

之所以使用这可能在15年前已与反射(慢)的问题,但至少今天没有任何意义了。

而且产生正常的应用程序流内一个NullPointerException每次和因此产生这样的一个重要的例外,并用这可以被认为是一个缺陷的调试会话不必要的干扰。

所以最后的结论:不要使用这段代码片段来验证兼容的类版本,而是使用反射。

相关问题