2013-12-02 3 views
4

У меня есть два метода следующим образомПочему это не перегружает?

public void add(List<String> strs) {...} 

public void add(List<Integer> ints) {...} 

я получаю ошибки компиляции, поэтому мой вопрос, почему это не перегружать, и то, что является преимуществом использования дженериков тогда?

Это ошибка, я получаю:

Method add(List<Integer>) has the same erasure add(List<E>) as another method in type Child 
+1

Какие ошибки вы получаете? – HonkyTonk

+5

[Тип Erasure] (http://docs.oracle.com/javase/tutorial/java/generics/erasure.html) – jaco0646

ответ

16

Java Дженерики время компиляции только свойство языка; родовые типы (такие как String и Integer здесь) будут стерты во время компиляции, а байт-код включает в себя только необработанный тип, как это:

public void add(List strs) {...} 

Из-за этого, вы не можете иметь несколько методов, чьи подписи различаются только в общих типах. Есть несколько способов обойти это, включая varargs и сделать ваш метод сам по себе общим, и лучший подход зависит от конкретной задачи.

Преимущество дженериков является то, что внутри метода, который принимает List<String>, вы можете добавлять или удалять элементы из List и относиться к ним, как только String объекты, без необходимости добавлять явное приведение везде.

4

Общие типы стираются во время выполнения. Итак, ваши public void add(List<String> strs) и public void add(List<Integer> ints){...........} - это тот же тип, компилятор просто устанавливает ограничения времени компиляции на то, что вы можете с ними сделать.

2

При компиляции какого-либо кода в отношении общего типа или метода компилятор разрабатывает то, что вы действительно имеете в виду (то есть, что такое аргумент типа для T), и во время компиляции проверяет, что вы поступаете правильно, но испускаемый код снова просто говорит в терминах j ava.lang.Object - компилятор при необходимости создает дополнительные приведения. Во время выполнения, List<Integer> и List<String> точно такие же; дополнительная информация о типе была удалена компилятором.

Таким образом, вы получаете ошибку компиляции.

0

В Java вы можете сделать это (перегрузка) следующим образом, список параметров содержит List.

public void add(List strs){ 

} 

Если вы используете разные защитный тип List с именем же методом, он будет рассматривать, как тот же метод.

0

Имейте в виду, что JVM не решит, какой метод вызывать во время выполнения. В отличие от виртуальных методов/метода, переопределяющих разрешение перегруженных методов, выполняются во время компиляции. Учебники Java на method overloading даже указывают на то, что «перегруженные методы следует использовать экономно ...».

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