4

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

这样我就可以拥有同名的不同实例。

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);
4

5 回答 5

10

你应该使用:

Foo.bar

并不是:

A.foo.bar

这就是警告的意思。

原因是bar不是. 相反,是全局的,在类上。编译器希望您全局引用它,而不是假装它是实例的成员。FoobarFoo

于 2008-09-17T19:21:29.987 回答
2

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

package1.Foo.bar
package2.Foo.bar
于 2008-09-17T19:24:53.503 回答
2

在以下位置创建对象后:

public static package1.Foo foo;

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

于 2008-09-17T19:27:12.360 回答
1

我同意其他人的观点,即您可能以错误的方式考虑这一点。顺便说一句,如果您只访问静态成员,这可能对您有用:

public class A {
    public static class Foo extends package1.Foo {}
}
public class B {
    public static class Foo extends package2.Foo {}
}
于 2008-09-17T22:06:55.003 回答
0

确实,Foo 实例可以访问 Foo 的静态字段,但请考虑“静态”一词。至少在这种情况下,这意味着“静态绑定”。由于 A.foo 是 Foo 类型,“A.foo.bar”不会向对象询问“bar”,它会直接进入类。这意味着即使一个子类有一个名为“bar”的静态字段,并且 foo 是该子类的一个实例,它也会得到 Foo.bar,而不是 FooSubclass.bar。因此,通过类名来引用它是一个更好的主意,因为如果您尝试利用继承,您将自食其果。

于 2008-09-17T19:27:31.983 回答