Come posso accedere correttamente alle classi membro statiche?
Domanda
Ho due classi e desidero includere un'istanza statica di una classe all'interno dell'altra e accedere ai campi statici dalla seconda classe tramite la prima.
In questo modo posso avere istanze non identiche con lo stesso nome.
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);
Funziona, ma ricevo un avviso "L'accesso al campo statico Foo.bar dovrebbe essere statico".Qualcuno può spiegare il motivo e offrire un'implementazione "corretta".
Mi rendo conto che potrei accedere direttamente alle istanze statiche, ma se hai una lunga gerarchia di pacchetti, diventa brutto:
assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1);
assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2);
Soluzione
Sono d'accordo con gli altri sul fatto che probabilmente stai pensando a questo nel modo sbagliato.Detto questo, questo potrebbe funzionare per te se accedi solo a membri statici:
public class A {
public static class Foo extends package1.Foo {}
}
public class B {
public static class Foo extends package2.Foo {}
}
Altri suggerimenti
Dovresti usare:
Foo.bar
E non:
A.foo.bar
Questo è il significato dell'avvertimento.
Il motivo è quello bar
non è un membro di un esempio Di Foo
.Piuttosto, bar
è globale, sulla classe Foo
.Il compilatore vuole che tu lo faccia riferimento a livello globale anziché fingere che sia un membro dell'istanza.
Non ha senso inserire queste due variabili statiche nelle classi finché è necessario accedere solo ai membri statici.Il compilatore si aspetta che tu possa accedervi tramite prefissi dei nomi di classe come:
package1.Foo.bar
package2.Foo.bar
Una volta creato l'oggetto in:
public static package1.Foo foo;
non è possibile accedervi in modo statico.Dovrai utilizzare il nome della classe e, ovviamente, il nome completo del pacchetto per indirizzare la classe poiché hanno lo stesso nome su pacchetti diversi
È vero che un'istanza di Foo ha accesso ai campi statici di Foo, ma pensa alla parola "statico".Significa "legato staticamente", almeno in questo caso.Poiché A.foo è di tipo Foo, "A.foo.bar" non chiederà "bar" all'oggetto, ma andrà direttamente alla classe.Ciò significa che anche se una sottoclasse ha un campo statico chiamato "bar", e foo è un'istanza di quella sottoclasse, otterrà Foo.bar, non FooSubclass.bar.Pertanto è un'idea migliore fare riferimento ad essa con il nome della classe, poiché se provi a sfruttare l'ereditarietà ti sparerai ai piedi.