简体   繁体   中英

Cannot return supertype in generic method

Some example code:

public class Main {
    class SomeType {

    }
    class A {
        protected <T extends SomeType> T createSomething()
        {
            return null; // Don't worry about this.
        }
    }
    class B extends A {
        @Override
        protected <T extends SomeType> T createSomething()
        {
            SomeType orig = super.createSomething();
            // do some stuff with orig
            return orig;
        }
    }
}

What am I getting wrong here?

On the line

return orig;

the compiler spits out the error that

Type mismatch: cannot convert from Main.SomeType to T

Thanks to <T extends SomeType> , we can be sure that T is always a subtype of SomeType , right? So why can't I just return the supertype SomeType ?

I've already read <? extends SuperType> cannot be applied to SuperType and Explanation of the get-put principle but I don't see how it applies here.

Thanks to <T extends SomeType> , we can be sure that T is always a subtype of SomeType , right?

Right.

So why can't I just return the supertype SomeType ?

Because it might not be a T !

Put it this way - imagine SomeType is Object , and T is String . You're suggesting that this code should work:

String foo() {
    return new Object();
}

It works the other way round - you can return a subtype reference for a method declared to return a supertype , but that's different.

The fix is easy though - just change orig to be of type T :

T orig = super.createSomething();

Then it compiles with no problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM