Interface with a Builder with a Factory and inheritance

Wang Weijun weijun.wang at oracle.com
Wed Jan 20 14:44:36 UTC 2016


Cool!

> On Jan 20, 2016, at 10:10 PM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
> 
> You might want something more precise, like:
> 
> interface F<S extends I>
> {
>        B<S, ?> getB();
>    }
> 
> 
> And then, Impl would become as follows:
> 
> static class Impl implements F<I2> {
> ...
> @Override
> public B2<I2, ?> getB() {
>            return new BImpl();
>        }
> 
> }
> 
> And the code that now is throwing a warning would simply become:
> 
> B2<I2,?> BImpl = f.getB(); //no cast needed

I see an error

A1.java:4: error: incompatible types: B<I2,CAP#1> cannot be converted to B2<I2,?>
        B2<I2,?> BImpl = f.getB();
                               ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends B<I2,CAP#1> from capture of ?
1 error

But you remind me I should write

interface F<S extends I, T extends B<S,?>> {
    T getB();
}

static class Impl implements F<I2,B2<I2,?>> {
    public B2<I2,?> getB() {
        return new BImpl();
    }
}

F<I2,B2<I2,?>> f = new Impl();
B2<I2,?> BImpl = f.getB();

and now there is no warning. (I still think those ?s are evil)

That said, my current work is adding B/B2/getB to existing APIs, and F was an old non-generics class. So maybe your short answer is best for me.

Thanks
Max

> 
> 
> I'm not saying that this is 100% the code you want - but I'm trying to point out how it could be made more precise when it comes to types.
> 
> Maurizio


More information about the compiler-dev mailing list