Pourquoi tous les champs d’une interface sont-ils implicitement statiques et finaux?

J’essaie simplement de comprendre pourquoi tous les champs définis dans une interface sont implicitement static et final . L’idée de garder les champs static sens pour moi, car vous ne pouvez pas avoir d’objects d’une interface, mais pourquoi ils sont final (implicitement)?

Quelqu’un sait-il pourquoi les concepteurs Java sont passés à la création de champs dans une interface static et final ?

Une interface ne peut pas avoir de comportement ou d’état car elle est destinée à spécifier uniquement un contrat d’interaction, aucun détail d’implémentation. Aucun comportement n’est imposé en ne permettant pas les corps de méthodes / constructeurs ou les blocs d’initialisation statiques / d’instance. Aucun état n’est appliqué en n’autorisant que des champs finaux statiques. Par conséquent, la classe peut avoir un état (état statique), mais l’état de l’instance n’est pas inféré par l’interface.

BTW: Une constante en Java est définie par un champ final statique (et par convention, le nom utilise UPPER_CASE_AND_UNDERSCORES).

RAISON D’ÊTRE final

Toutes les implémentations peuvent modifier la valeur des champs s’ils ne sont pas définis comme définitifs. Ils deviendraient alors une partie de la mise en œuvre. Une interface est une spécification pure sans implémentation.

RAISON D’ÊTRE static

S’ils sont statiques, ils appartiennent à l’interface et non à l’object, ni au type d’exécution de l’object.

Il y a quelques points ici:

Le fait que les champs d’une interface soient implicitement statiques ne signifie pas nécessairement qu’ils doivent être des constantes à la compilation, voire immuables. Vous pouvez définir par exemple

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

(Attention: faire cela dans une définition d’annotation peut perturber javac , du fait que ce qui précède comstack en fait un initialiseur statique.)

En outre, la raison de cette ressortingction est plus stylistique que technique, et beaucoup de gens aimeraient qu’elle soit assouplie .

Les champs doivent être statiques car ils ne peuvent pas être abstraits (comme le font les méthodes). Comme ils ne peuvent pas être abstraits, les implémenteurs ne pourront pas fournir logiquement les différentes implémentations des champs.

Je pense que les champs doivent être définitifs, car de nombreux implémenteurs différents peuvent accéder aux champs afin de pouvoir les modifier (comme la synchronisation). Aussi pour éviter qu’il soit ré-implémenté (caché).

Juste ma pensée.

Je considère que l’exigence que les champs soient définitifs est indûment ressortingctive et une erreur des concepteurs de langage Java. Il y a des moments, par exemple la gestion d’arborescence, où vous devez définir des constantes dans l’implémentation qui sont nécessaires pour effectuer des opérations sur un object du type d’interface. La sélection d’un chemin de code sur la classe d’implémentation est un kludge. La solution de contournement que j’utilise consiste à définir une fonction d’interface et à l’implémenter en renvoyant un littéral:

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

Cependant, il serait plus simple, plus clair et moins enclin à une implémentation aberrante d’utiliser cette syntaxe:

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

Spécification, contrats … L’instruction machine pour l’access aux champs utilise l’adresse de l’object plus le décalage de champ. Comme les classes peuvent implémenter de nombreuses interfaces, il est impossible de faire en sorte que le champ d’interface non finale ait le même décalage dans toutes les classes qui étendent cette interface. Par conséquent, différents mécanismes d’access au champ doivent être implémentés: deux access mémoire (get field offset, get field value) au lieu d’un plus, maintien du type de table de champ virtuel (analogue de la méthode virtuelle). Je suppose qu’ils ne voulaient tout simplement pas compliquer jvm pour des fonctionnalités qui peuvent être facilement simulées via des méthodes existantes.

En scala, nous pouvons avoir des champs dans les interfaces, bien qu’ils soient implémentés en interne comme expliqué ci-dessus (en tant que méthodes).

static :

Tout élément (variable ou méthode) static en Java peut être Classname.variablename tant que Classname.variablename ou Classname.methodname ou directement. Il n’est pas obligatoire de l’invoquer uniquement en utilisant le nom de l’object.

Dans l’interface, les objects ne peuvent pas être déclarés et static permet d’invoquer des variables via le nom de classe sans avoir besoin de nom d’object.

final :

Cela aide à maintenir une valeur constante pour une variable car elle ne peut pas être remplacée dans ses sous-classes.