variable una sirve que para modificador diferencia java interface static

sirve - ¿Por qué se usaría una interfaz anidada estática en Java?



static final java (11)

Acabo de encontrar una interfaz anidada estática en nuestra base de código.

class Foo { public static interface Bar { /* snip */ } /* snip */ }

Nunca he visto esto antes. El desarrollador original está fuera de alcance. Por lo tanto tengo que preguntar SO:

¿Cuáles son las semánticas detrás de una interfaz estática? ¿Qué cambiaría, si elimino la static ? ¿Por qué alguien haría esto?


En 1998, Philip Wadler sugirió una diferencia entre interfaces estáticas e interfaces no estáticas.

Por lo que puedo ver, la única diferencia en hacer que una interfaz no sea estática es que ahora puede incluir clases internas no estáticas; por lo que el cambio no invalidaría ningún programa Java existente.

Por ejemplo, propuso una solución al Problema de Expresión , que es la falta de coincidencia entre la expresión como "cuánto puede expresar su idioma" por un lado y la expresión como "los términos que está tratando de representar en su idioma" por otro lado .

Un ejemplo de la diferencia entre interfaces anidadas estáticas y no estáticas se puede ver en su código de ejemplo :

// This code does NOT compile class LangF<This extends LangF<This>> { interface Visitor<R> { public R forNum(int n); } interface Exp { // since Exp is non-static, it can refer to the type bound to This public <R> R visit(This.Visitor<R> v); } }

Su sugerencia nunca se hizo en Java 1.5.0. Por lo tanto, todas las demás respuestas son correctas: no hay diferencia entre las interfaces anidadas estáticas y no estáticas.


En Java, la interfaz / clase estática permite que la interfaz / clase se use como una clase de nivel superior, es decir, puede ser declarada por otras clases. Entonces, puedes hacer:

class Bob { void FuncA () { Foo.Bar foobar; } }

Sin la estática, lo anterior no podría compilar. La ventaja de esto es que no necesita un nuevo archivo de origen solo para declarar la interfaz. También asocia visualmente la barra de la interfaz a la clase Foo, ya que tienes que escribir Foo.Bar e implica que la clase Foo hace algo con las instancias de Foo.Bar.

Una descripción de los tipos de clase en Java .


Estático significa que cualquier parte de clase del paquete (proyecto) puede acceder a él sin utilizar un puntero. Esto puede ser útil u obstaculizar dependiendo de la situación.

El ejemplo perfecto de la utilidad de los métodos "estáticos" es la clase de matemáticas. Todos los métodos en matemáticas son estáticos. Esto significa que no tiene que salir de su camino, crear una nueva instancia, declarar variables y almacenarlas en aún más variables, solo puede ingresar sus datos y obtener un resultado.

La estática no es siempre tan útil. Si está haciendo una comparación de casos, por ejemplo, es posible que desee almacenar datos de varias maneras diferentes. No puedes crear tres métodos estáticos con firmas idénticas. Necesita 3 instancias diferentes, no estáticas, y luego puede y comparar, porque si es estático, los datos no cambiarán junto con la entrada.

Los métodos estáticos son buenos para devoluciones únicas y cálculos rápidos o datos fáciles de obtener.


La palabra clave estática en el ejemplo anterior es redundante (una interfaz anidada es automáticamente "estática") y puede eliminarse sin efecto en la semántica; Yo recomendaría que se elimine. Lo mismo ocurre con "público" en los métodos de interfaz y con "final pública" en los campos de interfaz: los modificadores son redundantes y solo agregan desorden al código fuente.

De cualquier manera, el desarrollador simplemente está declarando una interfaz llamada Foo.Bar. No hay más asociación con la clase adjunta, excepto que el código que no puede acceder a Foo tampoco podrá acceder a Foo.Bar. (Desde el código fuente: ¡el código de bytes o la reflexión pueden acceder a Foo.Bar incluso si Foo es un paquete privado!)

Es un estilo aceptable crear una interfaz anidada de esta manera si espera que se use solo de la clase externa, de modo que no cree un nuevo nombre de nivel superior. Por ejemplo:

public class Foo { public interface Bar { void callback(); } public static void registerCallback(Bar bar) {...} } // ...elsewhere... Foo.registerCallback(new Foo.Bar() { public void callback() {...} });


La pregunta ha sido respondida, pero una buena razón para usar una interfaz anidada es si su función está directamente relacionada con la clase en la que se encuentra. Un buen ejemplo de esto es un Listener . Si tuvieras una clase de Foo y quisieras que otras clases pudieran escuchar los eventos en ella, podrías declarar una interfaz llamada FooListener , lo cual está bien, pero probablemente sería más claro declarar una interfaz anidada y tener esas otras clases. implementar Foo.Listener (una clase anidada Foo.Event no es mala junto con esto).


La respuesta de Jesse es cercana, pero creo que hay un mejor código para demostrar por qué una interfaz interna puede ser útil. Mira el código de abajo antes de seguir leyendo. ¿Puedes encontrar por qué la interfaz interna es útil? La respuesta es que la clase DoSomethingAlready se puede crear una instancia con cualquier clase que implemente A y C; No solo la clase concreta del zoológico. Por supuesto, esto se puede lograr incluso si AC no es interno, pero imagina concatenar nombres más largos (no solo A y C), y hacer esto para otras combinaciones (por ejemplo, A y B, C y B, etc.) y fácilmente Mira cómo las cosas se salen de control. Sin mencionar que las personas que revisan su árbol de fuentes se verán abrumadas por las interfaces que solo tienen sentido en una clase. Para resumir, una interfaz interna permite la construcción de tipos personalizados y mejora su encapsulación .

class ConcreteA implements A { : } class ConcreteB implements B { : } class ConcreteC implements C { : } class Zoo implements A, C { : } class DoSomethingAlready { interface AC extends A, C { } private final AC ac; DoSomethingAlready(AC ac) { this.ac = ac; } }


Las interfaces de los miembros son implícitamente estáticas. El modificador estático en su ejemplo puede eliminarse sin cambiar la semántica del código. Véase también la especificación del lenguaje Java 8.5.1. Declaraciones de tipo de miembro estático



Si cambia la clase Foo en la interfaz Foo, la palabra clave "pública" en el ejemplo anterior también será redundante porque

La interfaz definida dentro de otra interfaz será pública de forma implícita.


Típicamente veo clases internas estáticas. Las clases internas estáticas no pueden hacer referencia a las clases contenidas, mientras que las clases no estáticas pueden. A menos que se encuentre con algunas colisiones de paquetes (ya existe una interfaz llamada Bar en el mismo paquete que Foo), creo que lo haría en su propio archivo. También podría ser una decisión de diseño para imponer la conexión lógica entre Foo y Bar. Tal vez el autor pretendía que Bar solo se usara con Foo (aunque una interfaz interna estática no aplicará esto, solo una conexión lógica)


Una interfaz interna tiene que ser estática para poder acceder. La interfaz no está asociada con instancias de la clase, sino con la clase en sí, por lo que se Foo.Bar con Foo.Bar , así:

public class Baz implements Foo.Bar { ... }

En la mayoría de los casos, esto no es diferente de una clase interna estática.