3

Take the following example:

class A
{
}

class B extends A
{
}

class MyParent
{
    private A _a;

    public A getMyValue()
    {
        return _a;
    }
}

class MyChild extends MyParent
{
    @Override
    public B getMyValue()
    {
        return (B)super.getMyValue();
    }
}

How come the previous is valid but the following is not:

class MyChild extends MyParent
{
    @Override
    public <T extends B> T getMyValue()
    {
        return (T)super.getMyValue();
    }
}

I would think that since T extends B it wouldn't cause conflict with the parent getMyValue() implementation due to type erasure; however, it seems that this is not the case. I get an error saying that they both have the same erasure.

To clarify as to why I don't think they should conflict: T extends B should always be at least B or any child class thereof. B inherits from A and therefore is assignable to type A.

Could someone break this down for me and is there any way around this that does not require changing either the A class or MyParent class (per my requirements)?


Looking at: https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html it states that the erasure that my example should resolve to is B, not A further confusing me.

Additionally, if I change the MyChild class to the following:

class MyChild<T extends B> extends MyParent
{
    @Override
    public T getMyValue()
    {
        return (T)super.getMyValue();
    }
}

It works!

Is there some difference in how erasure is resolved at the method vs class level?

d0nut
  • 2,841
  • 1
  • 16
  • 23
  • Slightly related: http://stackoverflow.com/q/12579153/1743880. Different in the regard that it actually works if the type bound is placed on the class rather than on the method. – Tunaki Apr 08 '16 at 19:55
  • Thank you, @Tunaki. Additionally, it's different in the regard that the generic upper bound is a child class of the overridden return type as opposed to the parent class, itself. – d0nut Apr 08 '16 at 19:57

0 Answers0