Как мне правильно получить доступ к статическим классам-членам?

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

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

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);
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
10 740
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вам следует использовать:

Foo.bar

И нет:

A.foo.bar

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

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

Для его варианта использования потребуется import package1.Foo; import package2.Foo;, что является незаконным, поскольку делает Foo неоднозначным.

erickson 17.09.2008 23:44

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

package1.Foo.bar
package2.Foo.bar

После того, как вы создали объект в:

public static package1.Foo foo;

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

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

Ответ принят как подходящий

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

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

Спасибо, это способ сделать это, даже если это не «java-способ». Я знал, что это возможно, потому что я мог создать статический внутренний класс, и он не выдал бы ошибок, но это было бы кошмаром обслуживания, и, следовательно, было бы справедливо обескуражено.

fijiaaron 19.09.2008 03:06

Другие вопросы по теме