日期:2014-05-20  浏览次数:20939 次

junit源代码中通过getMethod()获得test方法后,为什么仍然要多此一举检查是否为public???
junit中关于反射调用test方法的一段源代码如下所示:

    protected void runTest() throws Throwable {
        assertNotNull("TestCase.fName cannot be null", fName); // Some VMs crash when calling getMethod(null,null);
        Method runMethod = null;
        try {
            // use getMethod to get all public inherited
            // methods. getDeclaredMethods returns all
            // methods of this class but excludes the
            // inherited ones.
            runMethod = getClass().getMethod(fName, (Class[]) null);
        } catch (NoSuchMethodException e) {
            fail("Method \"" + fName + "\" not found");
        }
        if (!Modifier.isPublic(runMethod.getModifiers())) {
            fail("Method \"" + fName + "\" should be public");
        }

        try {
            runMethod.invoke(this);
        } catch (InvocationTargetException e) {
            e.fillInStackTrace();
            throw e.getTargetException();
        } catch (IllegalAccessException e) {
            e.fillInStackTrace();
            throw e;
        }
    }


runMethod = getClass().getMethod(fName, (Class[]) null);
此句返回的方法必定为public,为什么紧接着,又来了一句:
if (!Modifier.isPublic(runMethod.getModifiers()))
既然getMethod只能返回public方法,为什么还要多此一举,去检查此方法是否为public呢?
------解决方案--------------------
防御型编程风格
------解决方案--------------------
good question, 但是大师不一定出来的都是大师级的。

比如JDK,里面的String代码,就出现过一个性能方面的问题,至今(应该)还留在1.6的代码里面:

    public boolean contentEquals(CharSequence cs) {
        if (count != cs.length())
            return false;
        // Argument is a StringBuffer, StringBuilder
        if (cs instanceof AbstractStringBuilder) {
            char v1[] = value;
            char v2[] = ((AbstractStringBuilder)cs).getValue();
            int i = offset;
            int j = 0;
            int n = count;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
        }
        // Argument is a String
        if (cs.equals(this))
            return true;
        // Argument is a generic CharSequence
        char v1[] = value;
        int i = offset;
        int j = 0;
        int n = count;
        while (n-- != 0) {
            if (v1[i++] != cs.charAt(j++))
                return false;
        }