简体   繁体   English

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

[英]How do I correctly access static member classes?

I have two classes, and want to include a static instance of one class inside the other and access the static fields from the second class via the first. 我有两个类,并希望在另一个类中包含一个类的静态实例,并通过第一个类访问第二个类中的静态字段。

This is so I can have non-identical instances with the same name. 这样我可以使用相同名称的不同实例。

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

This works, but I get a warning "The static field Foo.bar shoudl be accessed in a static way". 这有效,但我得到一个警告“静态字段Foo.bar应该以静态方式访问”。 Can someone explain why this is and offer a "correct" implementation. 有人可以解释为什么会这样,并提供“正确”的实施。

I realize I could access the static instances directly, but if you have a long package hierarchy, that gets ugly: 我意识到我可以直接访问静态实例,但是如果你有一个很长的包层次结构,那就太丑了:

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

You should use: 你应该使用:

Foo.bar

And not: 并不是:

A.foo.bar

That's what the warning means. 这就是警告的意思。

The reason is that bar isn't a member of an instance of Foo . 原因是bar不是Foo 实例的成员。 Rather, bar is global, on the class Foo . 相反, bar是全球性的,在Foo类上。 The compiler wants you to reference it globally rather than pretending it's a member of the instance. 编译器希望您全局引用它,而不是假装它是实例的成员。

There is no sense in putting these two static variables in these to classes as long as you only need to access static members. 将这两个静态变量放入这些类中是没有意义的,只要您只需要访问静态成员即可。 The compiler expects you to access them trough class name prefixes like: 编译器希望您通过类名前缀来访问它们,例如:

package1.Foo.bar
package2.Foo.bar

Once you created the object in: 在以下位置创建对象后:

public static package1.Foo foo;

it isn't being accessed in a Static way. 它不是以静态方式访问的。 You will have to use the class name and, of course, the full package name to address the class since they have the same name on different packages 您必须使用类名,当然还有完整的包名来解决该类,因为它们在不同的包上具有相同的名称

I agree with others that you're probably thinking about this the wrong way. 我同意其他人的说法,你可能会以错误的方式思考这个问题。 With that out of the way, this may work for you if you are only accessing static members: 如果您只访问静态成员,那么这可能对您有用:

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

It's true that a Foo instance has access to Foo's static fields, but think about the word "static". 确实,Foo实例可以访问Foo的静态字段,但想想“静态”这个词。 It means "statically bound", at least in this case. 这意味着“静态约束”,至少在这种情况下。 Since A.foo is of type Foo, "A.foo.bar" is not going to ask the object for "bar", it's going to go straight to the class. 由于A.foo属于Foo类型,“A.foo.bar”不会向对象询问“bar”,它将直接进入该类。 That means that even if a subclass has a static field called "bar", and foo is an instance of that subclass, it's going to get Foo.bar, not FooSubclass.bar. 这意味着即使子类有一个名为“bar”的静态字段,而foo是该子类的一个实例,它也会得到Foo.bar,而不是FooSubclass.bar。 Therefore it's a better idea to reference it by the class name, since if you try to take advantage of inheritance you'll shoot yourself in the foot. 因此,通过类名引用它是一个更好的主意,因为如果你试图利用继承,你将会自己射击。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM