tl;dr
clojure 编译器依赖反射来查找 Java 互操作类方法的匹配签名,并且当找不到任何内容时,它会引发自己的异常。
在这种情况下IllegalArgumentException
是正确提出的,但是noMethodReport
显示错误消息会导致混乱。
And 这是负责它的源代码 on the clojure
github 仓库。
长版
首先,Java 互操作解析演练。
当 clojure 解析器发现.
点宏HostExpr
解析器处理解析,它尝试确定第二个参数是符号还是类。
如果它是一个类,则假定它是被调用的类的静态方法,并且解析继续StaticMethodExpr
.
解析器内的第一件事是尝试通过类的反射来查找方法:
List methods = Reflector.getMethods(c, args.count(), methodName, true);
if(methods.isEmpty())
throw new IllegalArgumentException("No matching method: " + methodName);
它正确找到并此时没有引发任何异常
然后它将参数添加到找到的方法中:
java.lang.reflect.Method m = (java.lang.reflect.Method) methods.get(i);
params.add(m.getParameterTypes());
之后尝试找到匹配的方法签名索引:
methodidx = getMatchingParams(methodName, params, args, rets);
对于这种情况返回“-1”并且method
保持为空。这就是解析阶段。
评价时间...
那么当invokeStaticMethod
被调用,它调用getMethods
on Reflector.java
它正确地找到“isWhitespace”的两个匹配签名。
最后是您在函数内部看到的令人困惑的消息:
static Object invokeMatchingMethod(String methodName, List methods, Object target, Object[] args)
对找到的方法进行参数匹配测试,尝试找到具有正确签名的方法:
for(Iterator i = methods.iterator(); i.hasNext();)
{
m = (Method) i.next();
Class[] params = m.getParameterTypes();
if(isCongruent(params, args))
如果没有找到匹配的签名,则会引发异常
if(m == null)
throw new IllegalArgumentException(noMethodReport(methodName,target));
因此,答案是 clojure 编译器依赖反射来查找方法的匹配签名,并且当找不到任何内容时,它会引发自己的异常。
在这种情况下IllegalArgumentException
是正确提出的,但是noMethodReport
显示错误消息会导致混乱。