Would you believe that the third time is a charm. I've added support for multiple parameters, primitives and just generally cleaned things up. Probably be where I leave it for awhile.|
Just a quick note about some quirks. First, the way the primitives are handled is that they are boxed into their object cousins. This works fine except you may run into situations where you have two methods that have the same perceived signature even though one is declared with a primitive and the other with an Object the corresponds to that primitive. The dispatcher masks any possible difference between the two. These two methods would be considered identical by the dispatch (Both will look like they take an integer object):
void aMethod(int aPrimitive) true
void aMethod(Integer anObject) true
Personally, I think of this as a feature since I don't necessarily like the differentiation between primitives and objects. Additionally, I don't think it would be a good programming practice to have these methods actually do something distinct - they should be identical except for the fact that one uses the primitive operations and the other uses the object operations. Should mean that all things being ideal, which method is chosen in this scenario is irrelevant.
Beyond that, I didn't test whether more than one maximally specific method is supported. I just go through and find one that is most specific (on a left to right basis). This is not necessarily the technique used by the Java compiler. It also doesn't flag a runtime error when the Java compiler would normally indicate that selecting the method is indecisive.
My thinking here is that the overhead added to check for variations is more than it's worth at this time. Covariance using this technique has a lot of loss ends anyhow, so this is just one more thing to take into consideration.
Among other things, I also didn't worry about the (a) handling of exceptions; (b) possible accessibility mismatches; and (c) invariant overriding.