¿Por qué todos los campos en una interfaz son implícitamente estáticos y finales?

Solo bash comprender por qué todos los campos definidos en una interfaz son implícitamente static y final . La idea de mantener campos static tiene sentido para mí, ya que no se pueden tener objetos de una interfaz, pero ¿por qué son final (implícitamente)?

¿Alguien sabe por qué los diseñadores de Java decidieron hacer los campos en una interfaz static y final ?

Una interfaz no puede tener comportamiento o estado porque está destinada a especificar solo un contrato de interacción, no 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.

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

Razón por ser final

Cualquier implementación puede cambiar el valor de los campos si no están definidos como definitivos. Entonces se convertirían en parte de la implementación. Una interfaz es una especificación pura sin ninguna implementación.

Razón por ser static

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

Hay un par de puntos pasados ​​por alto aquí:

El hecho de que los campos en una interfaz sean implícitamente estáticos, no significa que deban ser constantes en tiempo de comstackción, o incluso inmutables. Puede definir, por ejemplo

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

(Tenga en cuenta que hacer esto dentro de una definición de anotación puede confundir a javac , en relación con el hecho de que lo anterior en realidad se comstack en un inicializador estático).

Además, la razón de esta restricción es más estilística que técnica, y mucha gente quisiera verla relajada .

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 pueden ser accedidos por muchos implementadores diferentes, les permite ser modificables y pueden ser problemáticos (como la sincronización). También para evitar que se vuelva a implementar (oculto).

Solo mi pensamiento.

Considero que el requisito de que los campos sean definitivos es indebidamente restrictivo y un error de los diseñadores del lenguaje Java. Hay veces, por ejemplo, manejo de árbol, cuando necesita establecer constantes en la implementación que son necesarias 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 uso es definir una función de interfaz e implementarla devolviendo 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 simple, más clara y menos propensa a la implementación aberrante utilizar esta syntax:

 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"; ... } 

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

static :

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

En la interfaz, los objetos no se pueden declarar y los static hacen posible invocar variables solo a través del nombre de clase sin la necesidad de un nombre de objeto.

final :

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