【问题标题】:private field vs private static field in abstract class抽象类中的私有字段与私有静态字段
【发布时间】:2014-06-19 22:34:11
【问题描述】:

我对 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() 中使用的对象仍然是同一个对象吗?强>

【问题讨论】:

  • private static 无法从课堂外访问。

标签: java static field abstract-class private


【解决方案1】:

不,他们不是。 static 关键字表示该字段属于一个。它将是整个 VM 的单个实例。如果没有static 关键字,该字段属于一个对象,因此ValidComponent 或其子类的每个实例都会产生新的Validator 对象。

【讨论】:

  • 那么,这是否意味着一个对象即使无法访问它们也会继承其父类的私有字段?
  • 否,但它继承了可以访问该字段的 selfValidate() 方法。静态方法/字段不能被继承,这没有任何意义,与访问修饰符无关。
【解决方案2】:

我不确定,但我认为这不合适,将相同的Validator 用于不同的对象。您的 Valid* 类不共享相同的约束,因此存在相同的验证错误。共享同一个对象可能会导致不一致。

您可以将private static 更改为private,但您的设计可能从一开始就有问题。

也许factory pattern 更适合你。

回答你的问题

还是同一个对象?

不,他们不是。

【讨论】:

    【解决方案3】:

    是在 vuname.selfValidate() 和 vemail.selfValidate() 还是同一个对象?

    不,只有静态数据成员可以共享,无论是否私有。这里private static Validator validator = ...class ValidComponent的数据成员,而private Validator validator = ...object的数据成员,不能与其他对象共享。

    【讨论】:

      【解决方案4】:

      考虑一个私有变量,

      private String name;
      

      及其getter/setter 当然是public

      现在每个类都可以访问在其实现中使用私有变量的 getter/setter。这就是私有变量的目的,而不是从其他类直接访问它。

      您的情况与 selfValidate() 方法访问私有验证器的情况类似。通过他们的签名,selfValidate() 可以被子类访问。

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

      【讨论】:

        猜你喜欢
        • 2020-11-12
        • 1970-01-01
        • 2012-09-29
        • 2020-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        • 2013-07-14
        相关资源
        最近更新 更多