简体   繁体   English

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

[英]private field vs private static field in abstract class

I am confused about the scope of a private field versus a private static field of an abstract class. 我对抽象类的private字段和private static字段的范围感到困惑。 For example, consider the following classes and note the field validator , 例如,考虑以下类并注意字段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;
    }
}

The abstract class ValidComponent prepares method selfValidate() , in which the private static field, validator , is used. 抽象类ValidComponent准备方法selfValidate()其中,所述private static字段, validator被使用。

The ValidUsername and ValidEmail are subclasses that illustrate the intention of their base class: the method selfValidate() are used in their factory-methods to validate themself. ValidUsernameValidEmail是子类,它们说明了基类的意图:工厂自身方法中使用了selfValidate()方法来验证自身。

If my understanding is correct, when vuname.selfValidate() and vemail.selfValidate() are called, both use the same Validator object, ie ValidComponent.validator . 如果我的理解是正确的,则在vuname.selfValidate()vemail.selfValidate() ,它们都使用相同的Validator对象,即ValidComponent.validator

But what if I happen to change the modifiers of validator from private static to only private , are Validor objects used in vuname.selfValidate() and vemail.selfValidate() still the same object? 但是,如果我发生改变的修饰什么validatorprivate staticprivate的, Validor中使用对象vuname.selfValidate()vemail.selfValidate()仍然是相同的对象?

No they are not. 不,他们不是。 The static keyword means the field belongs to a class . static关键字表示该字段属于一个 It will be a single instance across whole VM. 这将是整个VM的单个实例。 Without the static keyword the field belongs to an object , so each instance of the ValidComponent or its subclasses will produce new Validator object. 如果没有static关键字,则该字段属于一个对象 ,因此ValidComponent的每个实例或其子类将产生一个新的Validator对象。

are Validor objects used in vuname.selfValidate() and vemail.selfValidate() still the same object? vuname.selfValidate()和vemail.selfValidate()中使用的Validor对象仍然是同一对象吗?

No, only static data member can be shared whether private or not. 不可以,无论静态数据成员是否私有,都只能共享。 Here private static Validator validator = ... is a data member of class ValidComponent whereas private Validator validator = ... is a data member of object and can't share with another object. 在这里, private static Validator validator = ... ValidComponent的数据成员,而private Validator validator = ...对象的数据成员,并且不能与另一个对象共享。

I'm not sure but I don't think this is appropriate, to use the same Validator for different objects. 我不确定,但我认为对不同的对象使用相同的Validator不合适。 Your Valid* classes don't share the same constraints therefore the same validation errors. 您的Valid*类不会共享相同的约束,因此会共享相同的验证错误。 Sharing the same object can cause inconsistency. 共享同一对象可能会导致不一致。

You can change private static to private , but your design might be problematic from the outset. 您可以将private static更改为private ,但是从一开始您的设计就可能有问题。

Maybe factory pattern suits you better. 也许工厂模式更适合您。

To answer your question 回答你的问题

are still the same object? 还是同一个对象?

No they are not. 不,他们不是。

Consider a private variable, 考虑一个私有变量,

private String name;

and its getter/setter which are ofcourse public . 及其获取getter/setterpublic

Now every class has access to getter/setter which in its implementation uses private variable. 现在,每个类都可以访问getter / setter,该方法在其实现中使用私有变量。 That's the purpose of private variables, not accessing it directly from other classes. 这就是私有变量的目的,而不是直接从其他类访问它。

Your case is similar where in private validator is being accessed by selfValidate() method. 您的情况与selfValidate()方法访问私有验证器中的情况类似。 By their signature, selfValidate() is accessible to subclasses. 通过其签名, selfValidate()可用于子类。

To answer your question about whether validator object will be different in case of non-static or not, then every class that accesses it will create a new instance of that object. 要回答有关验证器对象在非静态情况下是否会有所不同的问题,则访问它的每个类都将创建该对象的新实例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM