2016-11-12 5 views
2

Возможно ли иметь несколько методов с тем же именем, но принимает разные типы списков. Это, конечно, работает через переопределение, но java не может сказать разницу между двумя разными типами списков. Есть ли способ обойти это иначе, чем иметь разные имена? Например:java принимает разные типы списков с тем же именем метода

/** 
    * Prints a given in list, only works on numerical types 
    */ 
public static void printList(List list) { 
    for (int i = 0; i < list.size(); i++) { 
     System.out.print(list.get(i)); 
     if (i != list.size() - 1) System.out.print(", "); 
    } 
    System.out.println(); 
} 

не будет работать, если мы имеем

/** 
    * Prints a given in list of Vector3i 
    */ 
public static void printList(List<Vector3i> list) { 
    for (int i = 0; i < list.size(); i++) { 
     System.out.print("("); 
     System.out.print(list.get(i).x); 
     System.out.print(", "); 
     System.out.print(list.get(i).y); 
     System.out.print(", "); 
     System.out.print(list.get(i).z); 
     System.out.print(")"); 
     if (i != list.size() - 1) System.out.print(", "); 
    } 
    System.out.println(); 
} 

в том же классе.

+0

Вы не должны использовать 'List'. Это в основном ** Raw Type **. Это означает, что ваш первый метод примет любой тип, который наследует «Object». Таким образом, ваши оба метода могут использовать тип 'Тип'' Vector3i'. Итак, есть столкновение. – Blip

ответ

2

Вы не можете перегрузить методы, где у вас есть общий тип, как List<T>, из-за Java type erasure. Оба метода будут иметь одну и ту же подпись во время выполнения, а именно void printList(List list), что невозможно.

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

Вот пример:

public class Vector3i { 

    // Do stuff... 

    @Override 
    public String toString() { 
     return "(" + x + ", " + y + ", " + z +")"; 
    } 
} 

И ваша функция печати:

public static <T> void printList(List<T> list) { 
    for (int i = 0; i < list.size(); i++) { 
     System.out.print(list.get(i).toString()); 
     if (i != list.size() - 1) 
      System.out.print(", "); 
    } 
    System.out.println(); 
} 
+0

Обновлен ответ. Отсутствует скобка, и я добавил параметр типа, поэтому вы не используете ** raw ** types. – thatguy

2

Нет, из-за стирания стилей он был бы одного класса и фактически имел бы такую ​​же подпись, которая приводит к столкновению имен. Существует хороший SO нить об этом - Java generics - type erasure - when and what happens

0

Как описано ранее ответы, не существует способа сделать это из-за типа стирания, но я d хотел бы перефразировать вопрос:

Почему вас интересует тип вообще?

В этом случае вы не делаете ничего типоспецифичным, так что вы можете использовать эту форму вместо:

public void printList(List<?> list) { 
    // printing logic here 
} 

Это будет принимать список любого типа без необходимости беспокоиться о типе из список и по-прежнему безопасен по типу.

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