In §15.12.2.5 of the Java Language Specification they describe how Java chooses the most specific method to call from a list of both accessible and applicable methods.
There is one specific remark that I don't understand, namely:
(1) A type S is more specific than a type T for any expression if S <: T
The part that really bothers me is "any expression" .
To give an example why, I'll be quoting the previous paragraph that says when given two methods m 1 and m 2 we can say m 1 is more specific than m 2 for an invocation with argument expressions e 1 , ..., e k if:
m 2 is not generic, and m 1 and m 2 are applicable by strict or loose invocation, and where m 1 has formal parameter types S 1 , ..., S n and m 2 has formal parameter types T 1 , ..., T n , the type S i is more specific than T i for argument e i for all i (1 ≤ i ≤ n, n = k).
So if the type S i (m 1 ) is more specific than T i (m 2 ) with argument expression e i for all i, then m 1 is more specific than m 2
Now consider this:
int a(Number a) { return 1; } // m1
int a(Double a) { return 2; } // m2
Since Double <: Number
it follows that for any expression Double
is more specific than Number
(from quote 1).
We have:
m 1 : S 1 => Number
m 2 : T 1 => Double
But then if our argument argument expression e 1 is of type Number
m 2 is the most specific method since Double
is most specific for any expression (quote 1).
However, if we pass in a Number
to a()
the result is 1
ie. the method taking a Double
is not chosen. But quote 1 says that if Double
is a subtype of Number
for any expression Double
will be more specific, so how come it chooses a(Number)
?
What am I missing here?
Note : I know Number
is not assignable to Double
and it wouldn't make sense for the compiler to choose the other one, I'm just trying to see what I'm mis-interpreting from the first quote.
It turns out my misunderstanding was not as part of the quote but as to what an applicable function would be under loose or strict invocation.
More specifically strict/loose invocation contexts allow a set of conversions
Number
to Number
byte to short,int,long,float or double
Double
to Number
int to Integer
optionally followed by a widening reference conversion Integer to int
optionally followed by a widening primitive conversion In my example, I overlooked the fact that a widening reference conversion cannot be applied to Number
because Number
is not a subtype of Double
hence int a(Double a)
is not considered an applicable method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.