su99-bsa
su99-bsa

Reputation: 457

Java Generics and Method signature

Im trying to create overloading methods in java:

private BasesResponse getResponse(List<ClassA> classA) {
...
}

private BasesResponse getResponse(List<ClassB> classB) {
    ...
}

But eclipse is complaining about: Method getResponse(List<ClassA>) has the same erasure getResponse(List<E>) as another method in type BasisInformationEndpoint.

I thought method signature is method name + parmeter list.... but how can List<ClassA> be the same as List<ClassB>? Doesnt make sense to me.

Upvotes: 4

Views: 3254

Answers (8)

Vishal K
Vishal K

Reputation: 13066

This is because after going through type erasure both methods will come out to be like this:

private BasesResponse getResponse(List classA) {
...
}

private BasesResponse getResponse(List classB) {
    ...
}

Two same methods with same signature. Which ofcourse is not overloading , but a compile time error.

Upvotes: 1

Sanjaya Liyanage
Sanjaya Liyanage

Reputation: 4746

This is because compiler still supports legacy code and that is why it erase the generic type considering.you can find the same question is answered in here

Upvotes: 0

SeniorJD
SeniorJD

Reputation: 7202

Because for java the List<ClassA> and the List<ClassB> type parameter is the same as the List<E>.

You can resolve this problem only using different method names or, if ClassA and ClassB have the same parent, use getResponse(List<? extends ClassABParent> param).

Upvotes: 0

mel3kings
mel3kings

Reputation: 9405

Generic type erasure:

The reason for this is actually due to Generics, List<ClassA> and List<ClassB> Before java 1.5 there weren't any Generics, List were declared as is. just as List. Which means that you can put anything in specified list, before it would be legal to add Object, String, ClassA, Listener, etc to one List only. Generics were introduced for specifying the collections which type they would be getting. This is where: List<ClassA> ,List<String>, etc comes in to play.

However in order preserve the legacy systems of those who created their system pre-generics time this would be an issue, Generics are only imposed compile time, but in runtime it will still be the same underlying List before.

So to answer your question, to Eclipse this is both the same method signature receiving one parameter:

private BasesResponse getResponse(List classX) { ... }

Upvotes: 2

Suresh Atta
Suresh Atta

Reputation: 121998

The Java compiler also erases type parameters in generic method arguments.

You might see the two parameters as different type, but when the <> is removed the JVM will see two methods as the type of their parameters.

So overloading fails.

Upvotes: 1

fge
fge

Reputation: 121712

This is not possible. For backwards compatibility, generic parameters are discarded at runtime (unlike in, for instance, C#). This is called type erasure.

Therefore a List<Whatever>, at runtime, is just a List. Which means both of your methods have a prototype of BasesResponse getResponse(List), which is a compile error.

Upvotes: 1

Grzegorz Żur
Grzegorz Żur

Reputation: 49171

Java generic type erasure will make it

private BasesResponse getResponse(List classA) {
...
}

private BasesResponse getResponse(List classB) {
    ...
}

After type erasure it is the same for compiler.

Upvotes: 5

Karthik T
Karthik T

Reputation: 31952

The generic types (<...>) are present only before compilation stage, to be used for static typing.

Once compiled, those types are "erased" and List<ClassA> essentially becomes List. Thus you can see that when this happens, your two functions become identical.

This is called type erasure, as has been mentioned by the commenter.

Upvotes: 2

Related Questions