Question

J'ai deux classes et souhaite inclure une instance statique d'une classe à l'intérieur de l'autre et accéder aux champs statiques de la deuxième classe via la première.

Cela me permet d’avoir des instances non identiques portant le même nom.

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);

Cela fonctionne, mais un avertissement "Le champ statique Foo.bar doit être accédé de manière statique". Quelqu'un peut-il expliquer pourquoi et proposer un "correct"? mise en œuvre.

Je me rends compte que je pourrais accéder directement aux instances statiques, mais si vous avez une longue hiérarchie de paquets, ça devient moche:

assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1);
assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2);
Était-ce utile?

La solution

Je suis d’accord avec les autres pour dire que vous pensez probablement la mauvaise façon de procéder. Si cela n’est pas fait, cela peut fonctionner pour vous si vous accédez uniquement à des membres statiques:

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

Autres conseils

Vous devriez utiliser:

Foo.bar

Et non:

A.foo.bar

C'est ce que signifie l'avertissement.

La raison en est que la barre n'est pas membre d'une instance de Foo . Au contraire, la barre est globale, sur la classe Foo . Le compilateur souhaite que vous le référenciez globalement plutôt que de prétendre que c'est un membre de l'instance.

Il est inutile de mettre ces deux variables statiques dans ces classes dans des classes tant que vous n'avez besoin que d'accéder aux membres statiques. Le compilateur s'attend à ce que vous y accédiez via des préfixes de nom de classe tels que:

package1.Foo.bar
package2.Foo.bar

Une fois que vous avez créé l'objet dans:

public static package1.Foo foo;

il n’est pas accessible de manière statique. Vous devrez utiliser le nom de la classe et, bien sûr, le nom complet du package pour l’adresser à la classe car elles portent le même nom sur différents packages

Il est vrai qu'une instance de Foo a accès aux champs statiques de Foo, mais pensez au mot "statique". Cela signifie "lié statiquement", du moins dans ce cas. Puisque A.foo est de type Foo, "A.foo.bar" ne va pas demander à l'objet de "bar", il va aller directement à la classe. Cela signifie que même si une sous-classe a un champ statique appelé "bar", et que foo est une instance de cette sous-classe, il va obtenir Foo.bar, pas FooSubclass.bar. C’est donc une meilleure idée de le référencer par le nom de la classe, car si vous essayez de tirer parti de l’héritage, vous vous tirez une balle dans le pied.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top