Второй вызов compute выводит 2, потому что литерал hi во время компиляции известен как String, поэтому компилятор выбирает вторую сигнатуру метода, потому что String более специфичен, чем Object.
ли кто-нибудь помочь мне понятьраздел 15.12.2.5 JLS re: наиболее конкретный метод?
(следует дубинка и паста из JLS)
Кроме того, один метод члена переменной арности с именем m является более конкретным, чем другой метод члена переменной арности с тем же именем, если либо:
Один метод-член имеет 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,. , ., Tn-1, Tn []. Если второй метод является универсальным, тогда пусть 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
Я запутался, как интерпретировать результаты. Когда первым аргументом был String, компилятор выбрал метод с более конкретным подтипом. Когда первым аргументом был Object, компилятор выбрал метод с меньшим количеством необязательных переменных.
НОТА: Если вы не читаете этот раздел JLS, и вы даете ответ, который зависит от типоваргументыты мне не помогаешь. Если вы внимательно прочитаете JLS, кроме частей, относящихся к дженерикам, определение «более конкретный»зависит от заявленных аргументов, а не от реальных аргументов - это входит в игру в других частях JLS (не могу найти его в данный момент).
например для методов фиксированной арности,compute(String s)
будет более конкретным, чемcompute(Object o)
, Но я пытаюсь понять соответствующий раздел методов JLS re: variable arity.