2013-05-04 2 views
5

После кода дает ошибку компиляции с ошибкой «Дублированный методом»Дубликат метод, а метод-Перегрузки

static int test(int i){ 
    return 1; 
} 

static String test(int i){ 
    return "abc"; 
} 

Ожидается, что это и как перегруженный метод имеет одинаковую сигнатуру и отличается только типом возвращаемого значения.

Но следующий код компилируется нормально с предупреждением:

static int test1(List<Integer> l){ 
    return 1; 
} 

static String test1(List<String> l){ 
    return "abc"; 
} 

Как мы знаем, что Java Дженерики работает на Erasure, которые означают в байт-код, оба эти метода имеют точно такую ​​же подпись и отличается возвращаемый тип.

Furthur, к моему удивлению, следующий код снова дает ошибку компиляции:

static int test1(List<Integer> l){ 
    return 1; 
} 

static String test1(List l){ 
    return "abc"; 
} 

Как это второй код работает отлично, не давая какой-либо ошибки компиляции, хотя есть дубликат метод?

+0

Это потому, что как «Список списка», так и «Список » являются одним и тем же интерфейсом, вы, вероятно, захотите [прочитать] (http://docs.oracle.com/javase/6/docs/api/java/ util/List.html) 'Список '. – Azad

+0

@AzadOmer: Во время выполнения из-за Erasure весь список одинаковый. Таким образом, даже вторая должна давать ошибку компиляции, если только ее функция времени разработки. – Abhinav

+0

Вы также можете прочитать этот вопрос на самом деле, возможно, дубликат для вашего вопроса [Нажмите здесь] (http://stackoverflow.com/questions/8042561/java-override-constructor-using-listcustomobjects-same-erasure-error) – Azad

ответ

2

Решение перегруженных методов выполняется во время компиляции, а не во время выполнения, поэтому компилятор Java знает разницу между этими двумя во втором примере. В вашем третьем примере проблема заключается в том, что List<Integer> также является List, поэтому он не знал, какой из них использовать, если вы прошли в List<Integer>.

+0

Означает ли это, что файл класса может иметь два метода с точно такой же сигнатурой (в этом случае, из-за Erasure), но отличается только возвращаемым типом? – Abhinav

+0

@Abhinav Да. В моем компиляторе наличие двух таких методов приведет к ошибке с идентичными типами возврата и предупреждением с разными типами возврата. – nullptr

3
  1. Java не может определить, какой из них использовать, если параметры одинаковы. Таким образом, вместо этого возникает ошибка дублирующего метода.
  2. List из String и из Integer не могут быть друг в друга, поэтому методы разные. Нет ошибки.
  3. List из Integer также может быть использован как простой List ничего, так что Java не может определить, какой из них использовать, если поставлял List из Integer -> дубликата ошибки метода.
+1

@Point 2: они отличаются только во время разработки, но во время выполнения они одинаковы из-за Erasure. Это вызывает два вопроса: 1) Перегружает ли только функцию времени разработки? то есть. Если компилятор способен разрешить его во время разработки, виртуальная машина не имеет кроватки. 2) Может ли файл класса иметь два метода с одинаковой подписью, отличающихся только по типу возврата? – Abhinav

0

Ожидаемый результат.

Теперь давайте поговорим о :

Lets пытаются вызова этих функций.

List<Integer> intList; 
List<String> strList; 
test1(intList) 
test1(strList) 

Компилятор вызовет соответствующие методы.

Теперь третий

List<Integer> intList; 
List unknownList; 
test1(intList); 
test1(unknownList); 

Вау !! какой метод должен теперь компилятор! unknowList может быть List из Integers. Надеюсь, это поможет.

0

Основные изменения при перегрузке метода: ПАРАМЕТРЫ должны быть разными. В вашем случае оба метода test все время используют одинаковые параметры. Во-вторых, типы возврата могут или не меняться. Вместо этого попробуйте это для первого примера.

static int test(int i){ 
return 1; 
} 

static String test(List l){ 
return "abc"; 
} 

Ваш второй пример работает, потому что два List<String> и List<Integer> два разных параметра.

Третий пример невозможен, поскольку список целых чисел также может использоваться как список. После того, как код запускается, если целое число List передано как параметр, Java не сможет определить, какую из двух функций следует вызывать.

+0

«Список » и «Список » - это разные параметры только во время разработки. Во время выполнения они одинаковы из-за Erasure. – Abhinav

Смежные вопросы