1

I have run into a problem which is hard for me to understand why this happens.

I have a generic class B which extends generic class A and i have two methods accepting A and B. From method accepting A i want to call method with paramter B but this results in compilation error:

Ambiguous method call. Both method (A) in Main and method (B) in Main match

Here is a code snippet:

public class Main {

private static class A<T> {

}

private static class B<T> extends A {

}

public String method(A<String> arg) {
    return method((B<String>) arg));
}

public String method(B<String> arg) {
    return "some result";
}
}

However if I remove generic type from type A it compiles:

public class Main {

private static class A<T> {

}

private static class B<T> extends A {

}

public String method(A arg) {
    return method((B<String>) arg));
}

public String method(B<String> arg) {
    return "some result";
}
}

What is the reason of that ?

Edit: This issue is somehow related to java 8 because this code is compilable with JDK7

homik
  • 553
  • 5
  • 9
  • Possible duplicate of [Compiler error : reference to call ambiguous](https://stackoverflow.com/questions/14053596/compiler-error-reference-to-call-ambiguous) OR [this](https://stackoverflow.com/questions/32294140/java-8-reference-to-method-is-ambiguous) – Naman Sep 21 '17 at 09:57
  • Well, it does not quite make sense on what you are doing. Anyway: `A` is-NOT-a `A` . As you declare your `B extends A`, which means `B extends A`, which means, `B` is-a `A`. Given `A` is-NOT-a `A`, `B` is-NOT-a `A`, so the compiler is actually complaining it correctly by avoiding you to cast from `A` to `B` as it will never be lega – Adrian Shum Sep 25 '17 at 02:53

1 Answers1

2

Your class B extends A but it's not specifying its bounds nor any generic info

What I mean is that your line

private static class B<T> extends A { ... }

is equivalent to

private static class B<T> extends A<Object> { ... }

By changing it to

private static class B<T> extends A<T> { ... }

Your code will compile

Alberto S.
  • 7,409
  • 6
  • 27
  • 46
  • You are right it will compile but what if i don't want them to share the types ? I cast the parameter to B to explicitly call the other method but it looks like compiler ignores it – homik Sep 21 '17 at 09:58