Как дженерики в java работают для следующей программы?
public class Program {
private static <Program> void foo(Program x){
System.out.println(x+"-->1");
}
private static void foo(final int i){
System.out.println(i+"-->2");
}
public static void main(String[] args) {
Integer i = 10;
foo(i);
}
}
И результат:
10-->1
Мне не удалось найти подходящую дискуссию по этой теме. Однако ответ на другую тему немного смутил меня:
Возвращаемый тип общих методов Java
По их словам, общий <Program>
не имеет ничего общего с типом возвращаемого значения, но в моем случае, если я немного изменюсь на эту программу, как показано ниже, результат отличается.
public class Program {
private static <Integer> void foo(Program x){
System.out.println(x+"-->1");
}
private static void foo(final int i){
System.out.println(i+"-->2");
}
public static void main(String[] args) {
Integer i = 10;
foo(i);
}
}
Вывод:
10-->2
Я использую JDK1.7
Ответы
Ответ 1
В вашем первом примере вы фактически не указываете аргумент типа Program
, он является общим. Этот параметр типа не имеет ничего общего с вашим классом с именем Program
. Вы получите тот же результат, создав опечатку следующим образом:
public class Program {
private static <Programmmm> void foo(Programmmm x){
System.out.println(x+"-->1");
}
private static void foo(final int i){
System.out.println(i+"-->2");
}
public static void main(String[] args) {
Integer i = 10;
foo(i);
}
}
Однако во втором примере параметр буквально имеет тип Program
, и поэтому он не соответствует, когда вызывается как foo(10);
, и вы получаете результат от второго метода.
Ответ 2
В первом случае Program
- это имя общего параметра, используемого для метода. Это может быть любое имя. Важно то, что аргумент метода является объектом, поэтому, когда вы вызываете свой метод с аргументом Integer, он использует версию, которая принимает объект.
Во втором случае общий параметр называется Integer
(не делайте этого), но аргументом, который принимает метод, является Программа. Таким образом, вызывая его с помощью Integer, существует недопустимая версия Object
или целочисленная версия, поэтому она освобождает значение.
В терминах перегрузка метода, которая описывает порядок перегрузки. Это скажет вам, почему первая версия использует метод Object
вместо метода int
.
Вторая проблема заключается в том, что вы назвали ваши общие параметры конкретными типами, что запутывает. Легче понять, не делаете ли вы этого.
private static <T> void foo(T x){
System.out.println(x+"-->1");
}
Теперь это яснее, T
является параметризованным аргументом. В вашей второй версии
private static <T> void foo(Program x){
System.out.println(x+"-->1");
}
Теперь ясно, что ваш аргумент должен быть объектом Program, а не только любым объектом.