Interface with a Builder with a Factory and inheritance

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Jan 20 14:10:46 UTC 2016


So, there's a short answer and a long answer :-)

The short answer is to simply add this line:

@SuppressWarnings("unchecked")

before the variable declaration - as in:

@SuppressWarnings("unchecked")
B2<I2,?> BImpl = (B2<I2,?>)f.getB();

This should help in removing the warning.

That said, I think this warning also reveals a potential design issue in 
your classes; without diving too much in the details of your code, I 
note that you want factories for B - where B is a generic class with two 
type-variable.

Unfortunately the factory interface is very simple, and does not fully 
reflect those constraints - i.e. an instance of F can return any B, 
regardless of the parameterization; I don't think that's correct. I 
think that instead of:

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



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'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

On 20/01/16 13:47, Wang Weijun wrote:
> I am working on an Interface with a Builder with a Factory, and involving inheritance. The actual case can be viewed here [1], but I've distilled everything below in a single file.
>
> I've never written something with so many <> symbols. Although the code works, I am not sure if those ?s are used correctly, and there is still a warning
>
> $ javac -Xlint A1.java
> A1.java:4: warning: [unchecked] unchecked cast
>          B2<I2,?> BImpl = (B2<I2,?>)f.getB();
>                                           ^
>    required: B2<I2,?>
>    found:    B<CAP#1,CAP#2>
>    where CAP#1,CAP#2 are fresh type-variables:
>      CAP#1 extends I from capture of ? extends I
>      CAP#2 extends B<CAP#1,CAP#2> from capture of ? extends B<?,?>
> 1 warning
> $ java A1
> <N,C>
> <Nn,Cc>
>
> How can I make this warning going away?
>
> Thanks
> Max
>
> --
>
> public class A1 {
>      public static void main(String[] args) throws Exception {
>          F f = new Impl();
>          B2<I2,?> BImpl = (B2<I2,?>)f.getB();
>          I2 dad = BImpl.setName("N").setColor("C").build(null);
>          I2 son = BImpl.setName("n").setColor("c").build(dad);
>          System.out.println(dad);
>          System.out.println(son);
>      }
>
>      // Base interface and builder
>      interface I { String name(); }
>      interface B <S extends I, T extends B<S,T>> {
>          T setName(String s);
>          S build(S parent);
>      }
>
>      // Extended interface and builder
>      interface I2 extends I { String color(); }
>      interface B2<S extends I2, T extends B2<S,T>> extends B<S,T> {
>          T setColor(String s);
>      }
>
>      // Builder factory interface
>      interface F {
>          B <? extends I,? extends B<?,?>> getB();
>      }
>
>      // Implementation
>      static class Impl implements F {
>          static class C implements I2 {
>              String color, name;
>
>              public String color() {
>                  return color;
>              }
>
>              C(String name, String color) {
>                  this.color = color;
>                  this.name = name;
>              }
>
>              public String name() {
>                  return name;
>              }
>
>              public String toString() {
>                  return "<" + name + "," + color + ">";
>              }
>          }
>
>          static class BImpl implements B2<I2,BImpl> {
>              String color;
>              String name;
>
>              public BImpl setColor(String s) {
>                  this.color = s;
>                  return this;
>              }
>
>              public BImpl setName(String s) {
>                  this.name = s;
>                  return this;
>              }
>
>              public I2 build(I2 parent) {
>                  if (parent == null) {
>                      return new C(name, color);
>                  } else {
>                      return new C(parent.name() + name, parent.color() + color);
>                  }
>              }
>          }
>
>          public B <? extends I,? extends B<?,?>> getB() {
>              return new BImpl();
>          }
>      }
> }
>
> [1] http://cr.openjdk.java.net/~weijun/8058778/webrev.09/specdiff/java/security/cert/package-summary.html



More information about the compiler-dev mailing list