我在下面的帖子中需要一些帮助,因为我无法使用泛型从基础对象中获取派生对象,并且我不希望使用向下转换。
我对看到@Adam Arold 在帖子中设置的代码示例非常感兴趣。
public <T extends KeyException> T withId(final String Id) {
this.Id = Id;
return (T)this;
}
我无法评论该帖子,因为我需要代表点才能做到这一点,所以我发布了新帖子。
我基本上试过这个,我得到了一些警告,
public class KeyException <T extends KeyException<T>> {
private static final long serialVersionUID = 1L;
protected String Id;
public String getId() {
return Id;
}
// The type parameter T is hiding the type T
public <T extends KeyException<T>> T withId(final String Id) {
this.Id = Id;
return (T)this; //Type safety: Unchecked cast from KeyException<T> to T
}
}
使用泛型避免向下转换的正确方法是什么?
我的代码如下,
class Foo<TSelf extends Foo<?>> {
Class<TSelf> selfClass;
Foo(Class<TSelf> selfClass) {
if (!this.getClass().equals(selfClass))
throw new IllegalArgumentException();
this.selfClass = selfClass;
}
TSelf returnThis() {
return selfClass.cast(this);
}
}
class Bar extends Foo<Bar> {
Bar() {
super(Bar.class);
}
public int id = 10;
public static void main(String str[]) {
Bar b = new Bar();
b.id = 10;
Foo F = new Bar();
F.returnThis().id = 20; // Error, id cannot be resolved or is not a field
}
}
使用“ Fluent ”接口实现构建器模式,
// Base Class here
public abstract class Foo {
protected final String className;
protected Foo(Builder<?> builder) {
this.className = builder.className;
}
/* Builder class */
public static abstract class Builder<T extends Builder<?>> {
Class<T> selfClass;
protected String className;
public Builder(Class<T> selfClass) {
if (!this.getClass().equals(selfClass))
throw new IllegalArgumentException();
this.selfClass = selfClass;
}
public Builder<?> withClassName(String className) {
this.className = className;
return self();
}
public T self() {
return selfClass.cast(this);
}
/* build the Option */
public abstract Foo build();
private void validate() {
if(className != null)
throw new IllegalArgumentException();
}
}
}
// Derived Class here
public class Bar extends Foo {
private final String barProp;
private Bar(Builder builder) {
super(builder);
this.barProp = builder.barProp;
}
/* Builder class */
public static class Builder extends Foo.Builder<Bar.Builder> {
private String barProp = null;
public Builder() {
super(Bar.Builder.class);
}
public Bar.Builder withBarProp(String barProp) {
this.barProp = barProp;
return self();
}
public Bar build() {
if(barProp != null)
throw new IllegalArgumentException();
return new Bar(this);
}
}
public static void main(String[] args) {
Foo f1 = new Bar.Builder()
.withBarProp("Prop 1")
.withClassName("Bar") // works fine
.build();
Foo f2 = new Bar.Builder()
.withClassName("Bar")
.withBarProp("Prop 1") // does not work
.build();
}
}