I was just going to look at how to make the
arguments=true facility accessible to XML files, but so far I haven’t been able to figure it out. It seems so easy, just add a property to the node:
<predicate arguments="true">. Unfortunately, the XML only contains the definition of the predicate, but what I really need here is the signature of the method the predicate will be applied to, i.e. something like “IILjava/lang/String;”.
So I decided to ignore that issue for a while and focus on the other things that need to be done:
- reflection-based code
- accept a predicate method if the classes of the arguments are all superclasses of the classes actually passed
That’s when I noticed another limitation: I don’t think I can pass arguments for the reflection-based Thread Checker. At least not easily. The reflection-based Thread Checker has one method, and it gets called with the class and method name of the predicate it is supposed to invoke. If I were to pass the method’s arguments, then that method would have to have an arbitrary number of signatures. Of course I could use an array of
Object, but then I’d have to convert primitive types to objects, so I decided to ditch that issue for now, too. (@Update: Now that I am passing an array of
Object, of course I can support reflection.@)
As for allowing superclasses in the predicate method: Am I going to implement full-blown Java method invocation conversion? Ugh.
To quote the JLS, from 5.3 Method Invocation Conversion:
Method invocation conversion is applied to each argument value in a method or constructor invocation (§18.104.22.168, §15.9, §15.12): the type of the argument expression must be converted to the type of the corresponding parameter. Method invocation contexts allow the use of one of the following:
- an identity conversion (§5.1.1)
- a widening primitive conversion (§5.1.2)
- a widening reference conversion (§5.1.5)
- a boxing conversion (§5.1.7) optionally followed by widening reference conversion
- an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.
If, after the conversions listed above have been applied, the resulting type is a raw type (§4.8), an unchecked conversion (§5.1.9) may then be applied. It is a compile time error if the chain of conversions contains two parameterized types that are not not in the subtype relation.
If the type of an argument expression is either float or double, then value set conversion (§5.1.13) is applied after the type conversion:
- If an argument value of type float is an element of the float-extended-exponent value set, then the implementation must map the value to the nearest element of the float value set. This conversion may result in overflow or underflow.
- If an argument value of type double is an element of the double-extended-exponent value set, then the implementation must map the value to the nearest element of the double value set. This conversion may result in overflow or underflow.
If, after the type conversions above have been applied, the resulting value is an object which is not an instance of a subclass or subinterface of the erasure of the corresponding formal parameter type, then a ClassCastException is thrown.
It is a compile time error if a type declaration T has a member method m1 and there exists a method m2 declared in T or a supertype of T such that all of the following conditions hold:
- m1 and m2 have the same name.
- m2 is accessible from T.
- The signature of m1 is not a subsignature (§8.4.2) of the signature of m2.
- m1 or some method m1 overrides (directly or indirectly) has the same erasure as m2 or some method m2 overrides (directly or indirectly).
And from 8.4.2 Method Signature:
It is a compile-time error to declare two methods with override-equivalent signatures (defined below) in a class.
Two methods have the same signature if they have the same name and argument types.
Two method or constructor declarations M and N have the same argument types if all of the following conditions hold:
- They have the same number of formal parameters (possibly zero)
- They have the same number of type parameters (possibly zero)
be the formal type parameters of M and let be the formal type parameters of N. After renaming each occurrence of a Bi in N’s type to Ai the bounds of corresponding type variables and the argument types of M and N are the same.
The signature of a method m1 is a subsignature of the signature of a method m2 if either
- m2 has the same signature as m1, or
- the signature of m1 is the same as the erasure of the signature of m2.