私有字段与抽象类中的私有静态字段

时间:2014-05-03 07:53:29

标签: java static field abstract-class private

我对抽象类的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

ValidUsernameValidEmail是说明其基类意图的子类:方法selfValidate()在其工厂方法中用于验证自己。

如果我的理解是正确的,那么在调用vuname.selfValidate()vemail.selfValidate()时,两者都使用相同的Validator对象,即ValidComponent.validator

但是,如果我恰好将validator的修饰符从private static更改为仅privateValidor中使用的vuname.selfValidate()个对象和vemail.selfValidate()仍然是同一个对象?

4 个答案:

答案 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()

要回答关于验证器对象在非静态情况下是否会有所不同的问题,那么每个访问它的类都会创建该对象的新实例