1

刚接触Java,所以如果这看起来有点幼稚,我深表歉意。我试图更好地理解在实践中访问实例/成员变量的约定。

可以从非静态上下文中操作非静态实例变量吗?

例如,如何修改以下类定义以允许 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
模型一
优先

1
1
模型二

第二个例子...

1
1
模型一
优先

2
2
模型二

4

5 回答 5

3

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

例如: -

MyClass obj = null;
obj.staticVar = 10;

令人惊讶的是,上面的代码并没有 throw ,因为无论您如何访问它,都会NPE访问静态变量。class name

所以,obj.staticVar实际上是替换为MyClass.staticVar.

但反过来是不正确的。您不能non-static variable从 a 访问 a static context。因为,在静态上下文中,您没有任何reference实例。如果不引用该类的实例,您将无法访问实例变量。


话虽如此,还请注意,仅仅因为您可以做某事,并不意味着这是一个好主意。修改 a static variableinside a constructoror in anynon-static context是一个terrible想法。因为,您对这些变量所做的任何更改都将反映在该类的所有实例中。

相反,您应该使用 astatic-initialization block来初始化static变量。Static initialization block时执行class-loading,以初始化所有static变量。

于 2012-11-14T19:32:04.473 回答
2

如果您试图将这些属性作为static变量保留在类中,我强烈建议您不要这样做。这些idversion字段应该放在管理它们的特定类中,用于该对象和需要它们的每个对象。

这样,您可以向您的“IdManager”询问一个新的id和一个新的version并将它们分配给您创建的对象。

只是为了回答您的问题,一个static字段通过某个类的所有实例共享,因此任何修改都会影响所有实例。

于 2012-11-14T19:32:13.943 回答
2

静态字段在实例之间共享。

相反,实例字段对一个特定的实例范围是封闭的。

这就解释了为什么当您从第二个实例中获取它们时,您的字段似乎“重置”了。

因此,要增加第一个实例的字段,请提供一些像这样的公共方法:

public void incrementId(){
  id++;
}

这样您就可以通过以下方式实现您的要求:

fooOne.incrementId(); // id => 2

fooTwo.incrementId(); // id => 2
于 2012-11-14T19:34:16.957 回答
1

您所展示的实际上是所需的行为。

在您的第一个示例中,您声明实例变量并在构造函数中递增它们,这只会影响 instance

在第二个示例中,您声明静态/类变量并在构造函数中递增它们。当您实例化类两次并且每次构造函数调用都会递增类变量,从而将它们递增两次

于 2012-11-14T19:36:01.773 回答
0

我认为你真正想要的是这样的

    private static int globalID;
    private int id;
    private static int version;
    public String product;
    public String model;

    private Foo( ) {

        this.id = globalID;
        globalID++;
        //...
      }
于 2012-11-14T19:33:27.017 回答