2009-10-03 11 views
86

Estoy tratando de entender por qué todos los campos definidos en una interfaz son implícitamente static y final. La idea de mantener los campos static tiene sentido para mí, ya que no se pueden tener objetos de una interfaz, pero ¿por qué son final (implícitamente)?¿Por qué todos los campos en una interfaz son implícitamente estáticos y finales?

Cualquiera sabe por qué los diseñadores de Java hicieron la creación de los campos en una interfaz static y final?

Respuesta

115

Una interfaz no puede tener comportamiento o estado porque está destinada a especificar solo un contrato de interacción, sin detalles de implementación. No se aplica ningún comportamiento al no permitir cuerpos de método/constructor o bloques de inicialización estáticos/de instancia. No se aplica ningún estado permitiendo solo campos finales estáticos. Por lo tanto, la clase puede tener un estado (estado estático), pero la interfaz no deduce el estado de la instancia.

BTW: Una constante en Java se define mediante un campo final estático (y por convención el nombre usa UPPER_CASE_AND_UNDERSCORES).

+47

No es necesariamente cierto que los campos finales son constantes; eso solo está garantizado para los tipos primitivos. En general, la palabra clave final simplemente significa que la ubicación de la memoria no cambiará. – Pops

+7

No dije que los campos finales son constantes, solo que las constantes son campos finales. Tenga en cuenta que está permitido poner un campo final estático no primitivo en una interfaz. Aunque el contenido de ese campo podría cambiar, la referencia al mismo es constante. –

+1

@AdriaanKoster Dijo exactamente que el campo final es constante: * Ningún estado se aplica solo permitiendo constantes. * - esta oración implica que todos los campos finales son constantes. Puede tratar de seguir argumentando sobre las palabras que utilizó, pero obviamente su declaración es engañosa. –

9

Los campos deben ser estáticos porque no pueden ser abstractos (como los métodos pueden). Debido a que no pueden ser abstractos, los implementadores no podrán proporcionar lógicamente la implementación diferente de los campos.

Los campos deben ser definitivos, creo, porque los campos a los que pueden acceder muchos implementadores diferentes les permiten ser modificables y pueden ser problemáticos (como la sincronización). También para evitar que se vuelva a implementar (oculto).

Sólo mi pensamiento.

+0

NawMan, su explicación sobre "Los Felds deben ser estáticos ..." no tiene mucho sentido. Pero tenías mucha razón sobre "Los campos deben ser definitivos ..." – peakit

+1

No creo que tenga razón acerca de por qué los campos deben ser definitivos. Permitir que diferentes implementadores cambien un campo no es problemático, ya que de lo contrario la herencia sería problemática. Los campos deben ser finales, como dijo Adriaan, porque una interfaz es, y debería ser, apátrida. Una interfaz con un estado básicamente debe ser una clase abstracta. –

+0

Si tiene un campo 'public static' que no es' final', findbugs se quejará (¡correctamente!). –

16

Hay un par de puntos pasado por alto aquí:

El hecho de que los campos en una interfaz son implícitamente static final no quiere decir que deben ser constantes en tiempo de compilación, o incluso inmutable. Puede definir, p.

interface I { 
    String TOKEN = SomeOtherClass.heavyComputation(); 
    JButton BAD_IDEA = new JButton("hello"); 
} 

(Mira que hacer esto dentro de una definición de anotación se confuse javac, en relación con el hecho de que la anterior realidad compila a un inicializador estático.)

Además, la razón de esta restricción es más estilístico que técnico, y mucha gente lo haría like to see it be relaxed.

20

razón de ser final

Cualquier implementaciones pueden cambiar el valor de los campos si no se definen como final. Entonces se convertirían en parte de la implementación. Una interfaz es una especificación pura sin ninguna implementación.

razón de ser static

Si son estáticos, entonces ellos pertenecen a la interfaz, y no el objeto, ni el tipo de tiempo de ejecución del objeto.

2

Considero que el requisito de que los campos sean definitivos es indebidamente restrictivo y un error de los diseñadores del lenguaje Java. Hay momentos, p. manejo de árbol, cuando necesita establecer constantes en la implementación que son requeridas para realizar operaciones en un objeto del tipo de interfaz. Seleccionar una ruta de código en la clase de implementación es un kludge.La solución que yo uso es definir una función de interfaz e implementarlo mediante la devolución de un literal:

public interface iMine { 
    String __ImplementationConstant(); 
    ... 
} 

public class AClass implements iMine { 
    public String __ImplementationConstant(){ 
     return "AClass value for the Implementation Constant"; 
    } 
    ... 
} 

public class BClass implements iMine { 
    public String __ImplementationConstant(){ 
     return "BClass value for the Implementation Constant"; 
    } 
    ... 
} 

Sin embargo, sería más sencillo, más claro y menos propensos a la puesta en práctica aberrante de utilizar esta sintaxis:

public interface iMine { 
    String __ImplementationConstant; 
    ... 
} 

public class AClass implements iMine { 
    public static String __ImplementationConstant = 
     "AClass value for the Implementation Constant"; 
    ... 
} 

public class BClass implements iMine { 
    public static String __ImplementationConstant = 
     "BClass value for the Implementation Constant"; 
    ... 
} 
+0

Parece que se queja más de que los campos son estáticos que definitivos. –

0

Especificación, contratos ... La instrucción de máquina para el acceso de campo utiliza la dirección del objeto más el desplazamiento del campo. Dado que las clases pueden implementar muchas interfaces, no hay forma de que el campo de interfaz no final tenga el mismo desplazamiento en todas las clases que extienden esta interfaz. Por lo tanto, se debe implementar un mecanismo diferente para el acceso de campo: dos accesos a la memoria (get field offset, get field value) en lugar de uno más manteniendo el tipo de tabla de campo virtual (analog de la tabla de métodos virtuales). Supongo que simplemente no querían complicar jvm por la funcionalidad que se puede simular fácilmente a través de material existente (métodos).

En scala podemos tener campos en las interfaces, aunque internamente se implementan como he explicado anteriormente (como métodos).

-1

static:

Cualquier cosa (variable o método) que es static en Java puede invocarse como Classname.variablename o Classname.methodname o directamente. No es obligatorio invocarlo solo utilizando el nombre del objeto.

En la interfaz, los objetos no puede ser declarado y static hace posible invocar las variables sólo a través de nombre de la clase sin la necesidad de nombre del objeto.

final:

Ayuda a mantener un valor constante para una variable, ya que no puede suprimirse en sus subclases.

Cuestiones relacionadas