2008-09-17 4 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 way». Я знал, что это возможно, потому что я могу создать статический внутренний класс, и он не дал бы ошибок, но это было бы кошмаром для обслуживания, и, следовательно, его можно было бы обескуражить. – 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. Поэтому лучше всего ссылаться на это имя класса, поскольку, если вы попытаетесь воспользоваться наследованием, вы будете стрелять в ногу.