5

Following code gives compilation error with error "Duplicate Method"

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

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

This is expected as both the overloaded method have same signature and differ only in return type.

But the following code compiles fine with a warning:

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

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

As, we know the Java Generics works on Erasure, which mean in byte-code, both these method have exactly the same signature and differs with return type.

Furthur, to my surprise the following code again gives compilation error:

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

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

How is the second code working fine without giving any compilation error, though there is duplicate method?

Abhinav
  • 1,665
  • 2
  • 19
  • 24
  • That's because both `List list` and `List list` are the same interface, you probably want to [read about](http://docs.oracle.com/javase/6/docs/api/java/util/List.html) `List`. – Azad May 04 '13 at 19:35
  • @AzadOmer: At runtime because of Erasure all the List are same. So, even the second one should give compilation error, unless its a design time feature. – Abhinav May 04 '13 at 19:41
  • You can read also this question actually it's possible duplicate for your question [Click Here](http://stackoverflow.com/questions/8042561/java-override-constructor-using-listcustomobjects-same-erasure-error) – Azad May 04 '13 at 20:03
  • @AzadOmer: Going with the link provided by you, Even code snippet 2 should not compile, because at runtime they are methods with same signature but differing return type. – Abhinav May 06 '13 at 06:16

4 Answers4

3
  1. Java can not determine which one to use if the parameters are the same. So, it throws a duplicate method error instead.
  2. List of String and List of Integer are not directly conversible, so the methods are different. No error.
  3. List of Integer can also be used as a plain List of anything, so Java can't determine which one to use if supplied a List of Integer -> duplicate method error.
PurkkaKoodari
  • 6,383
  • 5
  • 33
  • 54
  • 1
    @Point 2: They are different only at Design Time but at Run Time they are same because of Erasure. This raises two question: 1) Is Overloading only a design time feature? ie. If the compiler is able to resolve it at Design Time, the Virtual Machine doesn't crib. 2) Can Class file have two methods with same signature just differing on return type? – Abhinav May 06 '13 at 06:11
2

Resolving overloaded methods is done at compile-time, rather than runtime, so the Java compiler would know the difference between the two in your second example. In your third example, the problem is that a List<Integer> is also a List, so it wouldn't know which one to use if you passed in a List<Integer>.

nullptr
  • 2,224
  • 1
  • 12
  • 22
  • Does it mean the class file can have two methods with exactly the same signature (In this case, because of Erasure) but differing only with return type? – Abhinav May 06 '13 at 06:06
  • @Abhinav Yes. On my compiler, having two such methods will cause an error with identical return types and a warning with differing return types – nullptr May 07 '13 at 01:21
0

First result is expected and correct.

Now lets talk of 2nd:

Lets try calling those functions.

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

Compiler will call respective methods.

Now 3rd

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

Woah!! which method should compiler call now!! 'cause unknowList can be a List of Integers. Hope it helps.

Amandeep Jiddewar
  • 1,632
  • 1
  • 13
  • 27
0

Essential changes for method overloading : PARAMETERs must be different. In your case both methods test uses the same parameters all the time. Secondly Return types may or may not change.Instead try this for first example.

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

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

Your second example works because two List<String> and List<Integer> are two different parameters.

Third example fails because List of Integer can also be used as a List.After the code runs if a List integer is passed as parameter, Java wont be able to determine which one to of the two functions should be called.

  • `List` and `List` are different parameter only at Design time. At run time they are same because of Erasure. – Abhinav May 06 '13 at 06:08