Как правильно получить доступ к статическим классам-членам? - PullRequest
4 голосов
/ 17 сентября 2008

У меня есть два класса, и я хочу включить статический экземпляр одного класса в другой и получить доступ к статическим полям из второго класса через первый.

Это значит, что у меня могут быть неидентичные экземпляры с одинаковыми именами.

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 ]

10 голосов
/ 17 сентября 2008

Вы должны использовать:

Foo.bar

А не:

A.foo.bar

Вот что означает предупреждение.

Причина в том, что bar не является членом экземпляра из Foo. Скорее, bar является глобальным для класса Foo. Компилятор хочет, чтобы вы ссылались на него глобально, а не притворялись, что он является членом экземпляра.

2 голосов
/ 17 сентября 2008

После создания объекта в:

public static package1.Foo foo;

Статический способ не доступен. Вам придется использовать имя класса и, конечно же, полное имя пакета, чтобы обратиться к классу, поскольку они имеют одинаковые имена в разных пакетах

2 голосов
/ 17 сентября 2008

Не имеет смысла помещать эти две статические переменные в классы, если вам нужен только доступ к статическим членам. Компилятор ожидает, что вы получите доступ к ним через префиксы имен классов, такие как:

package1.Foo.bar
package2.Foo.bar
1 голос
/ 18 сентября 2008

Я согласен с другими, что вы, вероятно, думаете об этом неправильно. При этом это может сработать, если вы обращаетесь только к статическим элементам:

public class A {
    public static class Foo extends package1.Foo {}
}
public class B {
    public static class Foo extends package2.Foo {}
}
0 голосов
/ 17 сентября 2008

Это правда, что экземпляр Foo имеет доступ к статическим полям Foo, но подумайте о слове "static". Это означает «статически связанный», по крайней мере, в этом случае. Поскольку A.foo относится к типу Foo, «A.foo.bar» не будет запрашивать у объекта «bar», он будет идти прямо к классу. Это означает, что даже если у подкласса есть статическое поле с именем «bar», а foo является экземпляром этого подкласса, он получит Foo.bar, а не FooSubclass.bar. Поэтому лучше ссылаться на него по имени класса, поскольку, если вы попытаетесь воспользоваться наследованием, вы выстрелите себе в ногу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...