Может ли кто-нибудь помочь мне понять раздел 15.12.2.5 JLS re: самый конкретный метод?
(далее следует дубленый вырезать и вставить из JLS)
Кроме того, один метод члена переменной arity с именем m является более конкретным, чем другой метод члена переменной arity с тем же именем, если:
- Один метод-член имеет n параметров, а другой - k параметров, где n> = k. Типы параметров первого метода-члена - T1,. . . , Tn-1, Tn [], типы параметров другого метода - U1,. . . , Ук-1, Ук []. Если второй метод является универсальным, пусть R1 ... Rp p1 - его параметры формального типа, пусть Bl - объявленная граница Rl, 1lp, пусть A1 ... Ap - фактические выведенные аргументы типа (§15.12.2.7) для этого вызова при начальных ограничениях Ti ‹---------------- Ui, 1ik-1, Ti ‹* Uk, kin и пусть Si = Ui [R1 = A1, ..., Rp = Ap] 1ik; в противном случае пусть Si = Ui, 1ik. Затем: для всех j от 1 до k-1, Tj ‹: Sj, и для всех j от k до n, Tj‹: Sk, и, если второй метод является универсальным, как описано выше, то Al ‹: Bl [R1 = A1, ..., Rp = Ap], 1lp.
- Один метод-член имеет k параметров, а другой - n параметров, где n> = k. Типы параметров первого метода - U1,. . . , Uk-1, Uk [], типы параметров другого метода - T1,. . ., Тн-1, Тн []. Если второй метод является универсальным, пусть R1 ... Rp p1 - его параметры формального типа, пусть Bl - объявленная граница Rl, 1lp, пусть A1 ... Ap - фактические выведенные аргументы типа (§15.12.2.7) для этого вызова при начальных ограничениях Ui ‹* Ti, 1ik-1, Uk ‹* Ti, kin и пусть Si = Ti [R1 = A1, ..., Rp = Ap] 1in; в противном случае пусть Si = Ti, 1in. Затем: для всех j от 1 до k-1, Uj ‹: Sj, и для всех j от k до n, Uk‹: Sj, и, если второй метод является универсальным, как описано выше, то Al ‹: Bl [R1 = A1, ..., Rp = Ap], 1lp.
Игнорируя обобщенные задачи, означает ли это, что varargs важнее подтипов, или подтипов важнее, чем varargs, при принятии решения о том, является ли один метод более конкретным, чем другой? Я не могу этого понять.
Конкретный пример: какой из следующих compute()
методов является «более конкретным» согласно JLS?
package com.example.test.reflect;
class JLS15Test
{
int compute(Object o1, Object o2, Object... others) { return 1; }
int compute(String s1, Object... others) { return 2; }
public static void main(String[] args)
{
JLS15Test y = new JLS15Test();
System.out.println(y.compute(y,y,y));
System.out.println(y.compute("hi",y,y));
}
}
Я не могу понять, что более конкретно; вывод распечатывает
1
2
Я не понимаю, как интерпретировать результаты. Когда первым аргументом была строка, компилятор выбрал метод с более конкретным подтипом. Когда первым аргументом был объект, компилятор выбирал метод с меньшим количеством необязательных переменных.
ПРИМЕЧАНИЕ. Если вы не читаете этот раздел JLS и даете ответ, зависящий от типов аргументов, вы мне не помогаете. Если вы внимательно прочитаете JLS, за исключением частей, относящихся к универсальным шаблонам, определение «более конкретного» зависит от заявленных аргументов, а не от фактических аргументов - это вступает в игру в других частях JLS (пока не могу найти).
например для методов фиксированной арности compute(String s)
будет более конкретным, чем compute(Object o)
. Но я пытаюсь понять соответствующий раздел методов JLS re: variable arity.
we say that the method invocation is ambiguous, and a compile-time error occurs
. - person MByD   schedule 17.05.2011