An instantiation is legal if the actual parameter satisfies the where
clause. Let us examine satisfaction more carefully. The compiler
checks whether a type t
(whether an interface, class, or formal
parameter) satisfies a where clause for a method or constructor m
by
verifying that a hypothetical call to m
would succeed.
The arguments to this hypothetical call have the same
types as in the where clause, but with all occurrences of
the formal parameter replaced by t
.
For example, consider the where clause in the SortedList
interface. The
instantiation SortedList[X]
is legal exactly
when the statement b = x1.lt(x2)
is legal,
where b
is a boolean
and both x1
and x2
have type X
.
Now, the call x1.lt(x2)
is legal if the lt
method of type X
accepts any supertype of X
, and returns any subtype of boolean
(i.e.,
boolean
itself). Therefore,
an instantiation can be legal even if the signatures of
constructors and methods of the actual type do not match exactly
with those in the constraints.
Instead we require only compatibility, using
the standard contra/covariance
rules for routine matching [Car88].
The only extension to these
rules is that any exceptions thrown by the provided method must be subtypes of
the exceptions given for that method in the where clause.
Because Java (like C++) allows overloading,
sometimes a constraint is matched by more than one method or constructor
of the actual type. In this case, the closest match
is selected; if there is no uniquely best match, a compile-time error results.
This is the same rule that is used in Java
to decide which method/constructor to use in a call.
For example, the unique method that would be called in the expression
x1.lt(x2)
is the one selected to satisfy the where clause.
Similar reasoning governs when protected and private methods can be used
as where-routines: a where-routine binding is legal if the bound routine
can be called legally at the point of instantiation. In our example, X
would satisfy the where clause only if its lt
method were visible to the code
performing the instantiation.
So far we have considered only instantiations in which the actual
parameter is a ``known'' type such as int
or SortedList[int]
.
However, the actual in an instantiation can also be a formal type
parameter. In this case, the satisfaction rule implies that
the parameter satisfies a where clause only if it has a compatible where
clause of its own. An example of such an
instantiation will be given in the next section.