Pregunta

Tengo dos clases y quiero incluir una instancia estática de una clase dentro de la otra y acceder a los campos estáticos de la segunda clase a través de la primera.

Esto es para poder tener instancias no idénticas con el mismo nombre.

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

Esto funciona, pero aparece una advertencia "Se debe acceder al campo estático Foo.bar de forma estática".¿Alguien puede explicar por qué es así y ofrecer una implementación "correcta"?

Me doy cuenta de que podría acceder a las instancias estáticas directamente, pero si tienes una jerarquía de paquetes larga, eso se pone feo:

assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1);
assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2);
¿Fue útil?

Solución

Estoy de acuerdo con otros en que probablemente estés pensando en esto de manera incorrecta.Dicho esto, esto puede funcionar para usted si solo accede a miembros estáticos:

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

Otros consejos

Deberías usar:

Foo.bar

Y no:

A.foo.bar

Eso es lo que significa la advertencia.

La razón es que bar no es miembro de un instancia de Foo.Bastante, bar es global, en la clase Foo.El compilador quiere que hagas referencia a él globalmente en lugar de pretender que es miembro de la instancia.

No tiene sentido poner estas dos variables estáticas en clases siempre que solo necesite acceder a miembros estáticos.El compilador espera que accedas a ellos a través de prefijos de nombres de clases como:

package1.Foo.bar
package2.Foo.bar

Una vez que creaste el objeto en:

public static package1.Foo foo;

No se accede a él de forma estática.Tendrá que usar el nombre de la clase y, por supuesto, el nombre completo del paquete para dirigirse a la clase, ya que tienen el mismo nombre en diferentes paquetes.

Es cierto que una instancia de Foo tiene acceso a los campos estáticos de Foo, pero piense en la palabra "estático".Significa "estáticamente vinculado", al menos en este caso.Dado que A.foo es del tipo Foo, "A.foo.bar" no le pedirá al objeto "bar", irá directamente a la clase.Eso significa que incluso si una subclase tiene un campo estático llamado "barra" y foo es una instancia de esa subclase, obtendrá Foo.bar, no FooSubclass.bar.Por lo tanto, es mejor hacer referencia a ella por el nombre de la clase, ya que si intentas aprovechar la herencia te dispararás en el pie.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top