2008-09-17 31 views
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 shoudl静态访问”。 有人可以解释为什么这是,并提供一个“正确的”实现。

我知道我可以直接访问静态实例,但如果你有很长的包层次,即得到丑:

assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1); 
assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2); 

回答

1

我同意别人的看法,你可能是在想这个错误的方法。因此,如果您只访问静态成员,这可能适用于您:

public class A { 
    public static class Foo extends package1.Foo {} 
} 
public class B { 
    public static class Foo extends package2.Foo {} 
} 
+0

谢谢,就是这样做,即使它不是“java方式”。我知道这是可能的,因为我可以创建静态的内部类,它不会给出错误,但这将是一个维护噩梦,因此正确地劝阻。 – fijiaaron 2008-09-18 23:06:05

11

你应该使用:

Foo.bar 

而不是:

A.foo.bar 

这就是警告的意思。

原因是bar不是Foo实例的成员。相反,bar是全球性的,类别Foo。编译器希望您在全局范围内引用它,而不是假装它是实例的成员。

+0

他的用例需要`import package1.Foo; import package2.Foo;`,这是非法的,因为它使得Foo不明确。 – erickson 2008-09-17 19:44:25

2

只要您只需要访问静态成员,将这两个静态变量放在类中就没有任何意义。 编译器期望你访问这些槽类的名称前缀,如:

package1.Foo.bar 
package2.Foo.bar 
+0

这种“丑陋”的方式是消除警告的正确方法。 – erickson 2008-09-17 19:46:36

2

一旦你创建的对象:

public static package1.Foo foo; 

它不是一个静态的方式被访问。您将不得不使用类名称,当然还要使用完整的包名称来解决该类,因为它们在不同的包中具有相同的名称

0

确实,Foo实例可以访问Foo的静态字段,但考虑一下单词“静态”。这意味着“静态绑定”,至少在这种情况下。由于A.foo是Foo类型的,因此“A.foo.bar”不会要求对象提供“bar”,它将直接进入课程。这意味着即使一个子类有一个名为“bar”的静态字段,并且foo是该子类的一个实例,它也会得到Foo.bar,而不是FooSubclass.bar。因此,最好用类名引用它,因为如果你尝试利用继承,你就会在脚下自我射击。