Unexpected compiler warning for return type <T extends ...> "

When I compile the following Java code (using Oracle JDK 1.7.0_25):

public class StackOverflowQuestion {

    interface Example {

        <T extends Example> T init();
    }

    static class ExampleImpl implements Example {

        @Override
        public ExampleImpl init() {
            return this;
        }
    }
}

      

I am getting a warning:

StackOverflowQuestion.java:11: warning: [unchecked] init()
  in ExampleImpl implements <T>init() in Example
        public ExampleImpl init() {
                           ^
  return type requires unchecked conversion from ExampleImpl to T
  where T is a type-variable:
    T extends Example declared in method <T>init()

      

I can't figure out why it says "The return type requires an unchecked conversion" as the class implements Example

, as far as I can see, its actual return type.

Can someone explain to me what happened?

+3


source to share


2 answers


Generic method is assumed to Example

work where it T

can be any type that extends Example

, but you tried to implement it in ExampleImpl

such a way that it always returns.It ExampleImpl

may be ok if ExampleImpl

is the only class that implements Example

, but if there are others, you can get ClassCastException

at runtime.

In the following example, we create a new one ExampleImpl

, refer it to the base interface, and then call the generic method init()

with T

equal ExampleImpl2

. He is supposed to return ExampleImpl2

, but since you did this

, he chose ClassCastException

. This is why your code must generate a warning.



public class StackOverflowQuestion {

    interface Example {

        <T extends Example> T init();
    }

    static class ExampleImpl implements Example {

        @Override
        public ExampleImpl init() {
            return this;
        }
    }

    static class ExampleImpl2 implements Example {

        @Override
        public <T extends Example> T init() {
            return null;
        }
    }

    public static void main(String[] args) {
        ExampleImpl2 e2 = ((Example) new ExampleImpl()).<ExampleImpl2>init();
    }
}

      

+3


source


My java is a little rusty, but can you get the derived class back in an overridden method?

public class StackOverflowQuestion {



interface Example {

    Example init();
}

static class ExampleImpl implements Example {

    @Override
    public ExampleImpl init() {
        return this;
    }
}

      

}

+2


source







All Articles