SelfType 指的是方法所运行的类
Java 中并没有这个概念,在方法重载协变返回值可能会使用到。
1
| protected Object clone()
|
子类实现clone()
方法时,需要强制转换cast
类型
1 2 3 4
| @Override public Person clone(){ return (Persion)super.clone(); }
|
在Builder模式中如果子类扩展父类Builder,会发现编译不过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class PersonBuilder {
private String name;
public PersonBuilder withName(String name) { this.name = name; return this; }
public Person build() { return new Person(name); }
}
public class EmployeeBuilder {
public EmployeeBuilder withName(String name) { return (EmployeeBuilder) super.withName(name); }
}
|
1 2 3 4 5 6
| Employee doe = new EmployeeBuilder() .withName("John Doe") .withHiringDate(LocalDateTime.now()) .build();
|
解决方式是,重载对应的方法修改返回类型,利用类型转换返回子类类型
1 2 3
| public EmployeeBuilder withName(String name) { return (EmployeeBuilder) super.withName(name); }
|
另外一种解决方式是利用自身泛型类型PersonBuilder<T extends PersonBuilder>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public static abstract class PersonBuilder<T extends PersonBuilder<T>> { private String name;
public T withName(String name) { this.name = name; return selfType(); }
abstract T selfType();
public Person build() { Person person = new Person(); person.setName(name); return person; } }
public static class EmployeeBuilder extends PersonBuilder<Employee.EmployeeBuilder> { Date hiringData;
public EmployeeBuilder withHiringDate(Date date) { hiringData = date; return this; }
@Override EmployeeBuilder selfType() { return new EmployeeBuilder(); } }
|
调用上就是正常
1 2 3 4
| new Employee.EmployeeBuilder() .withName("Haha") .withHiringDate(new Date()) .build();
|
自身泛型避免了类型转换,不需要使用cast