1

Following code gives compile time error like

'Method print(List) has the same erasure print(List) as another method in type MethodOverLoadingGenericExample'

public static void main(String[] args) {

}

public void print(List<Employee> empList){
    System.out.println(empList);
}

public void print(List<Address> empList){
    System.out.println(empList);
}

class Employee {
    private String name;

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class Address {
    public int pincode;

    public void setPincode(int pincode) {
        this.pincode = pincode;
    }
    public int getPincode(){
        return pincode;
    }
}
eltabo
  • 3,749
  • 1
  • 21
  • 33
Yogesh
  • 715
  • 1
  • 7
  • 20
  • 1
    compile time error like ....Method print(List) has the same erasure print(List) as another method in type MethodOverLoadingGenericExample – Yogesh Oct 04 '16 at 10:31
  • Sorry... stupid rules deriving from the need to stay backward-compatible with Java 1.0 – Marko Topolnik Oct 04 '16 at 10:32

2 Answers2

1

Generics are checked at compile-time for type-correctness. The generic type information is then removed in a process called type erasure. For example, List will be converted to the non-generic type List, which ordinarily contains arbitrary objects. The compile-time check guarantees that the resulting code is type-correct.

Because of type erasure, type parameters cannot be determined at run-time. For example, when an ArrayList is examined at runtime, there is no general way to determine whether, before type erasure, it was an ArrayList or an ArrayList. Many people are dissatisfied with this restriction.[6] There are partial approaches. For example, individual elements may be examined to determine the type they belong to; for example, if an ArrayList contains an Integer, that ArrayList may have been parameterized with Integer (however, it may have been parameterized with any parent of Integer, such as Number or Object).

For details see Problems with type erasure section at https://en.wikipedia.org/wiki/Generics_in_Java

Mike Shauneu
  • 3,201
  • 19
  • 21
  • `generic type information is then removed in a process called type erasure` That's not actually true because methods retain their full signatures. How else would the compiler validate a call to `print(List empList)`? The true reason is that _when_ type erasure is applied, _then_ the result must be distinct. But it _isn't_ applied. – Marko Topolnik Oct 04 '16 at 10:47
  • Generics in Java are a language-only construction; they are implemented only in the compiler. The runtime has no knowledge of the generic type system; generics are not part of the JVM. Instead, generics classes and methods are transformed during compiling via a process termed type erasure. During this, the compiler replaces all generic types with their raw version and inserts casts/checks appropriately in client code where the type and its methods are used. How compiler will pick-up single implementation? – Mike Shauneu Oct 04 '16 at 11:10
  • You have very limited and skewed knowledge of what Java's type erasure actually is. The only thing that's erased is the type parameter attached to an instance of a generic class. Method parameters that specify parameterized types retain these in full. You also contradict yourself: `How compiler will pick-up single implementation?`---because it's _the compiler_, not _the runtime_. Or do you think types are erased so even the compiler can't see them? – Marko Topolnik Oct 04 '16 at 11:13
  • You are right @MarkoTopolnik (parameters that specify parameterized types retain). The compiler error arises the Java Language Specification ruled this sort of overloading out because of the conflicts that would arise with raw types in legacy code. – Mike Shauneu Oct 04 '16 at 11:32
  • Exactly. It's just stupid legacy haunting us and making Generics even less useful. – Marko Topolnik Oct 04 '16 at 11:33
0

Generic type parameters are erased in compile time, so these two methods become indistinguishable and that's why it's an error.

Filipp Voronov
  • 4,077
  • 5
  • 25
  • 32
  • If this was true, how would the compiler type-check a call to `print(List)`? – Marko Topolnik Oct 04 '16 at 10:49
  • @MarkoTopolnik It checks before erasure. At runtime there is no type parameters. – Filipp Voronov Oct 04 '16 at 10:52
  • Did you notice that this question doesn't involve runtime in any way? It's a question about _compiler_ errors. Plus, it isn't even true that there are no type params at runtime. You can reflect on the entire generic signature of a method or a field. – Marko Topolnik Oct 04 '16 at 10:53
  • @MarkoTopolnik, Compiling is preparing for Runtime. At Runtime there is no type parameters and thus these two methods will be indistinguishable so it's a compile error with aim of forbidding creation of this situation – Filipp Voronov Oct 04 '16 at 10:55
  • At runtime the particular method will already have been chosen. Do you realize that? Overloads are resolved _at compile time_. Which is why they could be safely erased from the runtime---only they _aren't erased_ and you can reflect on the entire generic type signature of this method. – Marko Topolnik Oct 04 '16 at 10:57