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

StackOverflow https://stackoverflow.com/questions/86607

  •  01-07-2019
  •  | 
  •  

Вопрос

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

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

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);
Это было полезно?

Решение

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

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

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

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

Foo.bar

И не:

A.foo.bar

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

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

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

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 .Поэтому лучше ссылаться на него по имени класса, поскольку, если вы попытаетесь воспользоваться преимуществами наследования, вы прострелите себе ногу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top