2

Is it possible to have multiple methods with the same name but takes in different List types. This of course works through overriding regularly but java is unable to tell the difference between two different List types. Is there a way around this other than having different names? For example:

  /**
   * 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();
}

would not work if we have

  /**
   * 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();
}

in the same class.

FacelessTiger
  • 79
  • 1
  • 1
  • 10
  • You should not use `List`. It is basically a **Raw Type**. What this means that your first method will take any type that inherits `Object`. So your both methods can take `Types` `Vector3i` as type. So there is a collision. – Blip Nov 12 '16 at 03:42

3 Answers3

2

No, because of type erasure it would be of the same class and effectively have the same signature which leads to name collision. There is nice SO thread about it - Java generics - type erasure - when and what happens

Community
  • 1
  • 1
Yegor Chumakov
  • 450
  • 4
  • 11
2

You cannot overload methods where you have a generic type like List<T>, because of Java type erasure. Both methods would have the same signature at runtime, namely void printList(List list), which is impossible.

However, you can always override toString or implement a custom print function in your classes and have a single printList method instead of two, which is the way to go here.

Here is an example:

public class Vector3i {

    // Do stuff...

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

And your print function:

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();
}
thatguy
  • 13,242
  • 6
  • 19
  • 33
  • Updated the answer. A parenthesis was missing and I added a type parameter, so you do not use **raw** types. – thatguy Nov 12 '16 at 03:57
0

As earlier answers describe, there isn't a way to do this due to type erasure, but I'd like to rephrase the question:

Why do you care about the type at all?

In this scenario you're not doing anything type-specific, so you can use this form instead:

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

This will accept a list of any type without the need to worry about the type of the list, and still be type safe.

Makoto
  • 96,408
  • 24
  • 164
  • 210