If there is no method with the required name and number of parameters, Saxon reports a compile-time error.
If there is only one method with the required name and number of parameters, then Saxon chooses it, and goes on to the next stage, which allocates converters for the supplied arguments.
If there are several methods in the class that match the localname, and that have the correct number
of arguments, then the system attempts
to find the one that is the best fit to the types of the supplied arguments: for example if the
call is f(1,2)
then a method with two int
arguments will be preferred
to one with two float
arguments. The rules for deciding between methods are quite complex. Essentially, for each candidate method,
Saxon calculates the "distance" between the types of the supplied arguments and the Java class of the
corresponding method in the method's
signature, using a set of tables. For example, the distance between the XPath data type xs:integer
and the Java class long
is very small, while the distance between an XPath xs:integer
and a Java Object
is much larger. If there is one candidate method where the distances of all arguments are less-than-or-equal-to
the distances computed for other candidate methods, and the distance of at least one argument is smaller,
then that method is chosen.
If there are several methods with the same name and the correct number of arguments, but none is preferable to the others under these rules, an error is reported: the message indicates that there is more than one method that matches the function call.
This binding is carried out statically, using the static types of the supplied arguments, not the dynamic
types obtained when the arguments are evaluated. If there is insufficient static type information to distinguish
the candidate methods, an error is reported. You can supply additional type information using the treat as
expression, or by casting. Often it is enough simply to declare the types of the variables used as arguments to the function
call.
The distances are calculated using the following rules (in order).
If the required type is Object
, the distance is 100.
If the required type is one of the following Saxon-specific classes (or is a superclass of that class), then the distance is as given:
net.sf.saxon.om.SequenceIterator
: 26
net.sf.saxon.om.ValueRepresentation
: 25
net.sf.saxon.value.Value
: 24
net.sf.saxon.om.Item
: 23
net.sf.saxon.om.NodeInfo
: 22
net.sf.saxon.om.DocumentInfo
: 21
net.sf.saxon.value.AtomicValue
, 20
Note that Saxon does not recognize the classes defined in the s9api package for use with extension functions
(for example, XdmNode
and XdmAtomicValue
)
If the static type of the supplied argument allows more than one item, the distance is the first one of the following that applies:
If the method expects java.lang.Collection
or a class that implements Collection
: 30
If the method expects an array: 31
In all other cases: 80
Note that the item type of the supplied value plays no role in choosing the method to call, even though it could potentially be used to disambiguate overloaded methods when arrays or parameterized collection types are used.
Otherwise (the static type allows only one item):
If the static type of the supplied value matches node()
: 80
If the static type of the supplied value is a wrapped Java object, then 10 if the class of the object matches the required Java class, else -1 (meaning this method is not a candidate)
Otherwise, the value given in the table of atomic types below.
The distances for atomic types are given below. If there is no entry for the combination of supplied type and required type, the method is removed from consideration. For unboxed types (int, float, etc) the distance is always one less than the corresponding boxed type (java.lang.Integer, java.lang.Float).
Supplied type |
Required type |
xs:boolean |
BooleanValue, Boolean |
xs:dateTime |
DateTimeValue, Date |
xs:date |
DateValue, Date |
xs:decimal |
DecimalValue, BigDecimal, Double, Float |
xs:double |
DoubleValue, Double |
xs:duration |
DurationValue |
xs:float |
FloatValue, Float, Double |
xs:integer |
IntegerValue, BigInteger, BigDecimal, Long, Integer, Double, Float |
xs:short |
IntegerValue, BigInteger, BigDecimal, Long, Integer, Short, Double, Float |
xs:byte |
IntegerValue, BigInteger, BigDecimal, Long, Integer, Short, Byte, Double, Float |
xs:string |
StringValue, (String, CharSequence) |
xs:anyURI |
AnyURIValue, java.net.URI, java.net.URL, (String, CharSequence) |
xs:QName |
QNameValue, javax.xml.namespace.QName |
Saxon tries to select the appropriate method based on the static type of the arguments to the function call. If there are several candidate methods, and there is insufficient information available to decide which is most appropriate, an error is reported. The remedy is to cast the arguments to a more specific type.
A required type of one of the Java primitive types such as int
or bool
is treated as
equivalent to the corresponding boxed type (Integer
or Boolean
), except that with the boxed
types, an empty sequence can be supplied in the function call and is translated to a Java null value as the actual
argument.
The fact that a particular method is chosen as the target does not give a guarantee that conversion of the arguments will succeed at run-time. This is particularly true with methods that expect a node in an external object model such as DOM or XOM.