代码之家  ›  专栏  ›  技术社区  ›  fijiaaron

如何正确访问静态成员类?

  •  4
  • fijiaaron  · 技术社区  · 16 年前

    我有两个类,希望在另一个类中包含一个类的静态实例,并通过第一个类从第二个类访问静态字段。

    这是为了让我可以拥有具有相同名称的不相同实例。

    Class A 
    {
        public static package1.Foo foo;
    }
    
    Class B 
    {
        public static package2.Foo foo;
    }
    
    
    //package1
    Foo 
    {
        public final static int bar = 1;
    }
    
    // package2
    Foo
    {
        public final static int bar = 2;
    }
    
    // usage
    assertEquals(A.foo.bar, 1);
    assertEquals(B.foo.bar, 2);
    

    这是可行的,但我得到一个警告:“静态字段foo.bar应该以静态方式访问”。 有人能解释这是为什么并提供一个“正确”的实现吗?

    我意识到我可以直接访问静态实例,但是如果您有一个较长的包层次结构,这会变得很难看:

    assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1);
    assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2);
    
    5 回复  |  直到 16 年前
        1
  •  1
  •   jon    16 年前

    我同意其他人的看法,你可能认为这是错误的。如果您只访问静态成员,那么这样做可能对您有用:

    public class A {
        public static class Foo extends package1.Foo {}
    }
    public class B {
        public static class Foo extends package2.Foo {}
    }
    
        2
  •  10
  •   Jason Cohen    16 年前

    你应该使用:

    Foo.bar
    

    而不是:

    A.foo.bar
    

    这就是警告的含义。

    原因是 bar 不是 实例 属于 Foo . 更确切地说, 酒吧 是全球性的,在课堂上 . 编译器希望您全局引用它,而不是假装它是实例的成员。

        3
  •  2
  •   axk    16 年前

    把这两个静态变量放到类中是没有意义的,只要您只需要访问静态成员。 编译器希望您通过类名称前缀访问它们,例如:

    package1.Foo.bar
    package2.Foo.bar
    
        4
  •  2
  •   Fernando Barrocal    16 年前

    在以下位置创建对象后:

    public static package1.Foo foo;
    

    无法以静态方式访问它。您必须使用类名,当然,还必须使用完整的包名来寻址类,因为它们在不同的包上具有相同的名称。

        5
  •  0
  •   easeout    16 年前

    确实,foo实例可以访问foo的静态字段,但请考虑“static”一词。它的意思是“静态绑定”,至少在本例中是这样。由于a.foo是foo类型,“a.foo.bar”不会向对象要求“bar”,它将直接进入课堂。这意味着,即使一个子类有一个名为“bar”的静态字段,而foo是该子类的一个实例,它将得到foo.bar,而不是fooosubclass.bar。因此,最好用类名来引用它,因为如果你试图利用继承的优势,你会自食其果。