应该从Java中的非静态上下文操纵实例变量

bdicta 发布于 2019-02-11 constructor 最后更新 2019-02-11 21:14 6 浏览

如果这看起来有点幼稚,我只好让我的脚受到Java的影响,所以我很抱歉。我试图更好地理解在实践中访问实例/成员变量的约定。

Can a non-static instance variable be manipulated from a non-static context?
例如,如何修改以下类定义以允许id和version变量增加。
    class Foo {
private int id;
        private int version;
        public String product;
        public String model;
private Foo( ) {
// Can these variables be accessed from a non-static context?
            id++;
            version++;
}
        ...
与静态字段相比...
      class Foo {
private static int id;
        private static int version;
        public String product;
        public String model;
private Foo( ) {
id++;
            version++;
}
        ...
第一个例子...
1
1
Model One
First 1
1
Model Two
Second
第二个例子...
1
1
Model One
First 2
2
Model Two
Second
已邀请:

nnam

赞同来自:

您可以从non-static context访问static-variable,因为static variables绑定到一个类。因此,即使您在non-static context中访问它,也可以像在static context中一样访问它。 例如: -

MyClass obj = null;
obj.staticVar = 10;
令人惊讶的是,上面的代码不会抛出NPE,因为无论您如何访问它,都会在class name上访问静态变量。 因此,obj.staticVar实际上已替换为MyClass.staticVar。 但事实恰恰相反。您无法从static context访问non-static variable。因为,在静态上下文中,您没有任何reference到实例。并且您无法在不引用该类的实例的情况下访问实例变量。
话虽如此,还要注意,仅仅因为你可以做某事,并不意味着这是一个好主意。在constructor或任何non-static context中修改static variableterrible的想法。因为,您对这些变量所做的任何更改都将反映在该类的所有实例中。 相反,您应该使用static-initialization block来初始化static变量。 Static initialization blockclass-loading时执行,以初始化所有static变量。

seaque

赞同来自:

如果你试图将这些属性保留为类中的static变量,我强烈反对你这样做。那些idversion字段应该放在管理它们的特定类中,用于该对象以及需要它们的每个对象。 这样,您可以向“IdManager”询问新的id和新的version,并将其分配给您创建的对象。 只是回答你的问题,static字段通过某个类的所有实例共享,因此任何修改都会影响所有实例。

daut

赞同来自:

我觉得你真正想要的是这样的

    private static int globalID;
    private int id;
    private static int version;
    public String product;
    public String model;
private Foo( ) {
this.id = globalID;
        globalID++;
        //...
      }

nsunt

赞同来自:

静态字段跨实例共享。 相反,实例字段关闭到一个特定的实例范围。 这就解释了为什么当你从第二个实例获取它们时,你的字段似乎“重置”了。 因此,要增加第一个实例的字段,请提供一些像这样的公共方法:

public void incrementId(){
  id++;
}
这样您就可以实现以下要求:
fooOne.incrementId(); // id => 2
fooTwo.incrementId(); // id => 2

mqui

赞同来自:

你所展示的实际上是所期望的行为。 在第一个示例中,您声明实例变量并在构造函数中递增它们,这只会影响实例。 在第二个示例中,您声明静态/类变量并在构造函数中递增它们。当您将类实例化两次时,每个构造函数调用都会增加类变量,从而将它们递增两次。