I was reading this article, , about subclassing a builder class. I understood the article but there was one small bit that bothered me. There was this method,
public static Builder<?> builder() {
return new Builder2();
}
When I changed Builder<?>
to Builder
, a raw type, the compiler would not compile the code. The error was,
Rectangle.java:33: error: cannot find symbol
System.out.println(Rectangle.builder().opacity(0.5).height(250);
What was the additional information passed to the compiler using the additional <?>
? I suspected it was the compiler which could not figure the right instance during compilation. If I remove the comment markers in (A) the code compiled and ran fine. All the time it was referring to the Rectangle instance. So, my guess is it was the compiler which failed.
It would be great if someone can point me to an article that explains this or leads to find out more information to this. Thanks.
I have pasted the code here:
public class Shape {
private final double opacity;
public static class Builder<T extends Builder<T>> {
private double opacity;
public T opacity(double opacity) {
this.opacity = opacity;
return self();
}
/* Remove comment markers to make compilation works (A)
public T height(double height) {
System.out.println("height not set");
return self();
}
*/
protected T self() {
System.out.println("shape.self -> " + this);
return (T) this;
}
public Shape build() {
return new Shape(this);
}
}
public static Builder<?> builder() {
return new Builder();
}
protected Shape(Builder builder) {
this.opacity = builder.opacity;
}
}
public class Rectangle extends Shape {
private final double height;
public static class Builder<T extends Builder<T>> extends Shape.Builder<T> {
private double height;
public T height(double height) {
System.out.println("height is set");
this.height = height;
return self();
}
public Rectangle build() {
return new Rectangle(this);
}
}
public static Builder<?> builder() {
return new Builder();
}
protected Rectangle(Builder builder) {
super(builder);
this.height = builder.height;
}
public static void main(String[] args) {
Rectangle r = Rectangle.builder().opacity(0.5).height(250).build();
}
}