我对抽象类的private
字段与private static
字段的范围感到困惑。例如,请考虑以下类并记下字段validator
,
abstract class ValidComponent {
private static Validator validator = ... //(statement to instantiate new Validator)
/**
* This method is to be used by subclasses in their factory-methods
* to do some validation logic after instantiation.
*/
protected void selfValidate() {
//validation logic
...
validator.validate(this); // <<< This line uses the validator
...
}
}
class ValidUsername extends ValidComponent {
private @NotEmpty String core;
private ValidUsername(String unamestr) {
this.core = unamestr;
}
/** This is the factory-method who use selfValidate() */
public static ValidUsername create(String unamestr) {
ValidUsername vuname = new ValidUsername(unamestr);
vuname.selfValidate();
return vuname;
}
}
class ValidEmail extends ValidComponent {
private @Email String core;
private ValidEmail(String emailstr) {
this.core = emailstr;
}
/** This is the factory-method who use selfValidate() */
public static ValidEmail create(String emailstr) {
ValidEmail vemail = new ValidEmail(emailstr);
vemail.selfValidate();
return vemail;
}
}
抽象类ValidComponent
准备方法selfValidate()
,其中使用private static
字段validator
。
ValidUsername
和ValidEmail
是说明其基类意图的子类:方法selfValidate()
在其工厂方法中用于验证自己。
如果我的理解是正确的,那么在调用vuname.selfValidate()
和vemail.selfValidate()
时,两者都使用相同的Validator
对象,即ValidComponent.validator
。
但是,如果我恰好将validator
的修饰符从private static
更改为仅private
,Validor
中使用的vuname.selfValidate()
个对象和vemail.selfValidate()
仍然是同一个对象?
答案 0 :(得分:2)
不,他们不是。 static
关键字表示该字段属于类。它将是整个VM的单个实例。如果没有static
关键字,则该字段属于对象,因此ValidComponent或其子类的每个实例都将生成新的Validator对象。
答案 1 :(得分:1)
是vuname.selfValidate()和中使用的Validor对象 vemail.selfValidate()仍然是同一个对象?
不,只有私有或非私有才能共享静态数据成员。此处private static Validator validator = ...
是类有效成分的数据成员,而private Validator validator = ...
是对象的数据成员,无法与其他对象共享。
答案 2 :(得分:1)
我不确定,但我认为这不合适,对不同的对象使用相同的Validator
。您的Valid*
类不会共享相同的约束,因此验证错误相同。共享同一个对象可能会导致不一致。
您可以将private static
更改为private
,但从一开始您的设计可能会出现问题。
也许factory pattern更适合你。
回答你的问题
仍然是同一个对象?
不,他们不是。
答案 3 :(得分:0)
考虑一个私有变量,
private String name;
及其getter/setter
当前为public
。
现在每个类都可以访问getter / setter,它在其实现中使用私有变量。这是私有变量的目的,而不是从其他类直接访问它。
您的情况类似于selfValidate()
方法访问私有验证程序的情况。通过他们的签名,子类可以访问selfValidate()
。
要回答关于验证器对象在非静态情况下是否会有所不同的问题,那么每个访问它的类都会创建该对象的新实例。