Better

业精于勤荒于嬉

Java 泛型-SelfType

Better's Avatar 2020-01-12 Java

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()
// 返回的是 PersonBuilder
.withName("John Doe")
// 方法无法找到
.withHiringDate(LocalDateTime.now()) // compile error :(
.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

This article was last updated on days ago, and the information described in the article may have changed.