2010-01-03 11 views

Respuesta

48

En versiones anteriores de Java, Marker Interfaces eran la única forma de declarar metadatos sobre una clase. Por ejemplo, la interfaz de marcador serializable le permite al autor de una clase decir que su clase se comportará correctamente cuando se serialice y se deserialice.

En Java moderno, las interfaces de marcador no tienen cabida. Se pueden reemplazar completamente por Annotations, lo que permite una capacidad de metadatos muy flexible. Si tiene información sobre una clase y esa información nunca cambia, las anotaciones son una forma muy útil de representarla.

+16

Me gustan mucho las anotaciones, pero en este caso tienen el inconveniente de ser un poco más complicado de verificar (en comparación con el uso de instanceof). Tampoco están tan bien integrados en javadoc (donde una forma rápida de ver qué implementa o no es simplemente buscarlo y ver la lista de clases de implementación). Entonces yo diría que todavía tienen un lugar, pero no es igualmente importante. – Fredrik

+9

@Chris, ¿tienes razón o está Josh Bloch aquí mismo? http://stackoverflow.com/a/5080547/632951 – Pacerier

+1

@Pacerier Yo diría que, dado que las interfaces de los marcadores no definen ningún comportamiento, esencialmente carecen de sentido para la seguridad del tipo.El hecho de que una clase se marque como serializable no significa que se pueda serializar correctamente, y la falta de la interfaz del marcador no implica que la serialización no funcione. ¡Simplemente puede significar que el desarrollador cometió un error al marcarlo! Si la interfaz en realidad tenía métodos (y ya no era un marcador), entonces impondría un contrato de comportamiento. También es mucho más trabajo incluir metadatos adicionales con una interfaz de marcador, mientras que con las anotaciones es parte del punto. –

4

Indica que la clase (y, en consecuencia, todos los campos que no son transitorios) son candidatos para la serialización. Y si usted está construyendo un marco dependiente de la serialización, que por supuesto puede escribir un método así:

public void registerObject(Serializable obj); 

para limitar las clases que está dispuesto a aceptar.

Dado que un objeto serializado necesita mantener la compatibilidad entre sistemas, la serialización es una decisión de diseño explícita y por lo tanto requiere el uso de la interfaz de marcador para identificar dichos candidatos.

También hay un aspecto de seguridad. No desea que todo sea serializable; de ​​lo contrario, puede exponer accidentalmente (por ejemplo) contraseñas u otros datos confidenciales a través de la serialización.

6

Dichas interfaces de marcador son útiles en el caso de que otro código tome decisiones dependiendo de si un objeto implementa alguna interfaz de marcador.

En el caso de Serializable, la reflexión se utilizará para serializar los campos de los objetos.

Ahora se prefieren las anotaciones, ya que no se propagan a las subclases.

Ver Marker interface pattern.

+2

Serializable, no ISerializable :) – Bozho

+1

sí metí la pata, siempre estoy anteponiendo mis nombres de interfaz con "I" :) –

+3

@Gregory Herejía, ¡esto es Java! E incluso en el mundo .NET, esta convención COM (mala) debe ser olvidada. –

2

Se llaman marcador interfaces. Y como su nombre lo indica, marca que algún objeto está disponible para cierto tipo de operaciones.

Serializable significa que el objeto es elegible para la serialización de Java, por ejemplo.

Se ha debatido si no deberían sustituirse por anotaciones, ya que sus funciones son bastante similares.

2

Si implementa una interfaz, entonces instanceof será verdadero. Si su interfaz no tiene nada que implementar, puede usar esto para marcar una clase con metadatos como las anotaciones para Java 1.5 y posteriores sin tener que forzar al implementador a hacer algo especial.

1

Tiene razón al razonar que una interfaz vacía no afecta la ejecución "estándar" del programa que se basa en la inspección/mutación de campos y en el envío de métodos.

Sin embargo, la interfaz de marcador es útil cuando se utiliza junto con la reflexión: Una biblioteca/método inspecciona (mediante reflexión) un objeto y funciona de manera diferente si su clase implementa la interfaz de marcador. A partir de Java5, hay muy poca necesidad de interfaces de marcadores: la misma función de "marcado" se puede lograr a través de anotaciones Java, que (una vez más) la mayoría de sus efectos se lograrán a través del código basado en la reflexión.

75

Joshua Bloch: Effective Java segunda edición, página 179

artículo 37: Use las interfaces de marcador para definir tipos

... Usted puede escuchar que marcador de anotaciones (artículo 35) hace que las interfaces del marcador sean obsoletas. Esta afirmación es incorrecta. Las interfaces de marcador tienen dos ventajas sobre las anotaciones de marcador. En primer lugar, las interfaces de marcador definen un tipo que se implementa mediante instancias de la clase marcada; marcador anotaciones no. La existencia de este tipo le permite detectar errores en tiempo de compilación que usted podría no captura hasta que el tiempo de ejecución si se ha utilizado una anotación de marcador ....

Personalmente creo que voy a inclino a Joshua de conocimiento superior sobre este tema.

+2

Sí ... muy bien :) – agpt

+0

El problema es que esto a menudo contradice el elemento 19: Usar interfaces solo para definir tipos. "Serializable" no es un tipo, es una propiedad/comportamiento. –

+3

En realidad, incluso "Serializable" puede verse como un tipo. Considere la siguiente firma de método: public void serialize (Serializable objectToSerialize); En este caso, es claro en el momento de la compilación que solo los objetos serializables pueden pasarse a "serializar", esto no es posible con las anotaciones. –

-1

El propósito principal es decirle al compilador que trata de manera diferente el objeto de la clase que implementó la interfaz de marcador.

+1

Esto es completamente incorrecto. El compilador de Java o JVM no hace nada especial para Serializable y otras interfaces de marcador, pero las clases de biblioteca java que lo consumen necesitan reconocer objetos Serializables y pueden considerarlo y procesar dichos objetos de forma diferente, pero no el compilador o la JVM. Este es un error común sobre las interfaces de Marker. –

-1

Observando detenidamente la interfaz de marcador en Java, p. Serializable, Clonable y Remote parece que se utilizan para indicar algo al compilador o JVM. Entonces, si JVM ve que una Clase es Serializable, realizó alguna operación especial en ella, de manera similar si JVM ve que una Clase es implementar Clonnable, realiza alguna operación para admitir la clonación. Lo mismo es cierto para RMI y la interfaz remota. En resumen, la interfaz Marker indica, señaliza o ordena a Compiler o JVM.

Leer más: http://javarevisited.blogspot.com/2012/01/what-is-marker-interfaces-in-java-and.html#ixzz2v6fIh1rw

+1

Esto es completamente incorrecto. El compilador de Java o JVM no hace nada especial para Serializable y otras interfaces de marcador, pero las clases de biblioteca java que lo consumen necesitan reconocer objetos Serializables y pueden considerarlo y procesar dichos objetos de forma diferente, pero no el compilador o la JVM. Este es un error común sobre las interfaces de Marker. –

Cuestiones relacionadas