如何在我的特定情况下使用泛型propery?该代码,然后再解释:Java中的泛型构建器
AbstractConstraint.java
public abstract class AbstractConstraint {
public abstract Constraint[] getConstraints();
}
AccountConstraint.java
public class AccountConstraint extends AbstractConstraint {
private Constraint<Range<Integer>> accountIdConstraint;
private Constraint<String> usernameConstraint;
private Constraint<String> passwordConstraint;
private Constraint<String> emailConstraint;
private AccountConstraint(Builder builder) {
this.accountIdConstraint = builder.accountIdConstraint;
this.usernameConstraint = builder.usernameConstraint;
this.passwordConstraint = builder.passwordConstraint;
this.emailConstraint = builder.emailConstraint;
}
@Override
public Constraint[] getConstraints() {
return new Constraint[] {
this.accountIdConstraint,
this.usernameConstraint,
this.passwordConstraint,
this.emailConstraint
};
}
public static class Builder extends ConstraintBuilder<AccountConstraint> {
private Constraint<Range<Integer>> accountIdConstraint;
private Constraint<String> usernameConstraint;
private Constraint<String> passwordConstraint;
private Constraint<String> emailConstraint;
public Builder() {
this.accountIdConstraint = null;
this.usernameConstraint = null;
this.passwordConstraint = null;
this.emailConstraint = null;
init();
}
public Builder accountId(final int val) {
this.accountIdConstraint = new Constraint<>(operation, truthed, new Range<>(val), "accountId");
return this;
}
public Builder accountId(final int min, final int max) {
this.accountIdConstraint = new Constraint<>(operation, truthed, new Range<>(min, max), "accountId");
return this;
}
public Builder accountId(final Range<Integer> accountId) {
this.accountIdConstraint = new Constraint<>(operation, truthed, accountId, "accountId");
return this;
}
public Builder username(final String username) {
this.usernameConstraint = new Constraint<>(operation, truthed, username, "username");
return this;
}
public Builder email(final String email) {
this.emailConstraint = new Constraint<>(operation, truthed, email, "email");
return this;
}
@Override
public AccountConstraint build() {
return new AccountConstraint(this);
}
}
}
ConstraintBuilder.java
public abstract class ConstraintBuilder<T> {
protected boolean truthed;
protected Operation operation;
protected void init() {
truthed = true;
operation = Operation.IS;
}
public ConstraintBuilder not() {
truthed = false;
return this;
}
public ConstraintBuilder like() {
operation = Operation.LIKE;
return this;
}
public abstract T build();
}
我希望能够调用new AccountConstraint.Builder().not().username("test");
但这是不可能的,因为我失去了“构建的参考”呃'在new AccountConstraint.Builder().not().
,即。我不能选择username("test")
了。
在哪些方面可以解决这个问题?我确实希望AccountBuilder.Builder
延伸ConstraintBuilder<AccountConstraint.Builder>
,这样我就不必重复共享方法了。
问候。
编辑:我设法得到它的工作:
请参阅下面的答案的变化。
我希望这个解决方案没有破坏任何Java基础知识,我希望它是一个比肮脏的黑客更多的解决方案。 如果有人可以查看此编辑,我会很高兴。
我不认为你会失去参考。从'not()'你要返回'this',它仍然指向当前的'Builder'实例。可能是我错过了一些东西。你试过了吗? –
是的,并且代码在Netbeans中不起作用。例如'new AccountConstraint.Builder()。'可以访问'not()'和'username(String)'。虽然'新的AccountConstraint.Builder()。not()。'只能访问'not()'。一个特别的情况是,在后者中,build()会返回类型Object,而在第一个时它将返回类型AccountConstraint。 – skiwi
他不会丢失引用,但他会丢失类型信息('not()'返回'ConstraintBuilder',而不是'Builder')。 – herman