MikeL
MikeL

Reputation: 2894

Java - generic classes hierarchy and generic methods overloading

I have a (non abstract) generic base class A<L,M>, an abstract generic sub class B<K, L, M> extends A<L,M> and a (non abstract) class C extends B<Integer, Integer, Void> :

public class A<L,M> { }

public abstract class B<K, L, M> extends A<L,M> { }

public class C extends B<Integer, Integer, Void> { }

I have a utils class that has a few methods, two are relevant here:

public static <K, L, M> void doSomething(B<K, L, M> b) {...}
public static <L, M>    void doSomething(A<L, M>    a) {...}

To be clear, both methods have the same name.
If I call doSomething(c); (where C c) it goes as expected to the 1st method.
My issue is with the following code (at another class that uses the utils):

private void doSomethingMoreComplex(A a) { // a is actually C
    Utils.doSomething(a);
}

So here a is actually C but it goes to the second method, I am not sure if I made a mistake in the code or this is actually the expected behavior.

Upvotes: 1

Views: 125

Answers (2)

Mureinik
Mureinik

Reputation: 311948

This is the expected behavior. The runtime type of a is inconsequential, as this method resolution is done in compile time. Since doSomething(B) cannot be applied to an argument of type A, the method is resolved to doSomething(A).

You could handle this yourself by explicitly downcasting a:

private void doSomethingMoreComplex(A a) { // a is actually C
    if (a instanceof B) {
        Utils.doSomething((B) a);
    } else {
        Utils.doSomething(a);
    }
}

... but, well, in a word - yuck.

The more idiomatic way to address this would be to have doSomething as a method of A and override (not overload) it in B.

Upvotes: 3

Andy Turner
Andy Turner

Reputation: 140494

or this is actually the expected behavior.

Yes, it's the expected behavior.

The compiler chooses which method is run, and it doesn't know that it is a B (because you've said it's an A). So it doesn't know if the first overload is safe to invoke, but it knows the second overload is.

Upvotes: 3

Related Questions