...
Code Block | ||
---|---|---|
| ||
public class Overloader { private static String display(ArrayList<Integer> aarrayList) { return "ArrayList"; } private static String display(LinkedList<String> llinkedList) { return "LinkedList"; } private static String display(List<?> llist) { return "List is not recognized"; } public static void main(String[] args) { // Single ArrayList System.out.println(display(new ArrayList<Integer>())); // Array of lists List<?>[] invokeAll = new List<?>[] {new ArrayList<Integer>(), new LinkedList<String>(), new Vector<Integer>()}; for (List<?> ilist : invokeAll) { System.out.println(display(ilist)); } } } |
At compile time, the type of the object array is List
. The expected output is ArrayList
, ArrayList
, LinkedList
, and List is not recognized
(because java.util.Vector
does not inherit from java.util.List
). The actual output is ArrayList
followed by three instances of List is not recognized
. The cause of this unexpected behavior is that overloaded method invocations are affected only by the compile-time type of their arguments: ArrayList
for the first invocation and List
for the others. Do not use overloading where overriding would be natural [Bloch 2008].
...
Code Block | ||
---|---|---|
| ||
class Overloader { public class Overloader { private static String display(List<?> llist) { return ( llist instanceof ArrayList ? "Arraylist" : (llist instanceof LinkedList ? "LinkedList" : "List is not recognized") ); } public static void main(String[] args) { // Single ArrayList System.out.println(display(new ArrayList<Integer>())); List<?>[] invokeAll = new List<?>[] {new ArrayList<Integer>(), new LinkedList<String>(), new Vector<Integer>()}; for (List<?> ilist : invokeAll) { System.out.println(display(ilist)); } } } |
Appicability
Ambiguous uses of overloading can lead to unexpected results.
...