# more specific method inference

Dan Smith daniel.smith at oracle.com
Thu Dec 19 15:34:49 PST 2013

```On Dec 13, 2013, at 3:32 PM, Rafkind, Jon <jon.rafkind at hp.com> wrote:

> I don't quite understand how more specific method inference (18.5.4) is
> supposed to work. Given these functions
>
> <Q extends Integer> void f(Q q){}
> <K extends Number> void f(K k){}
>
> f(12) // will call Integer
>
> I'm assuming for the moment that determining which function to choose
> requires the logic of 18.5.4, and if so I don't see how treating the
> type parameters of m1 as type variables allows reduction to take place.
>
> Using the terminology from 18.5.4:
>
> let m1 = <Q extends Integer> void f(Q q)
> let m2 = <K extends Number> void f(K k)
>
> S1 = Q
> P1 = K
> theta = [K:=a1]
> T1 = a1
> B = [a1 <: Number]
>
> S1 is a proper type (Q) but T1 is not (a1), so generate the constraint
> {Q <: a1}.
>
> B' = reduce({Q <: a1}, B)
>
> {Q <: a1} is reduced to the bound (S <: a1).
>
> B' = incorporate((S <: a1), [a1 <: Number])
> = S <: Number

I assume by "S" you mean "Q" here.

The resulting bound set (B') is
{ Q <: a1, a1 <: Number }

Which can be resolved: a1 = Q.

> And thats all. Technically B' is not false so I suppose the logic
> 'worked', but if m1 and m2 were reversed (so m1 = Number and m2 =
> Integer) then we would have selected the method that uses Number as a
> bound to be more specific. Also 'Integer' is no where in sight during
> the process.

'Integer' appears in incorporation: Q <: Number because Q extends Integer.

We'll get a similar bound set in the reverse:
{ K <: a1, a1 <: Integer }

But incorporation produces 'false' here, because K </: Integer.

> ----
> I wonder about the point of all of this in the first place. If we just
> instantiate the functions with their bounds and compare them as normal
> it seems to have the same result.
>
> <Q extends Integer> void f(Q q)
> <K extends Number> void f(K k)
>
> instantiate to
>
> void f(Integer q)
> void f(Number k)

The point, at the most basic level, is to write down what Java has always done (well, since Java 5) in Chapter 18. :-)

Try a more complex type in your parameter lists (like List<Q>), and you'll see that the approach you suggest will get different answers.

—Dan
```