web-dev-qa-db-fra.com

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 conserver les champs static me semble logique car vous ne pouvez pas avoir d'objets d'interface mais pourquoi ils sont final (implicitement)?

Tout le monde sait pourquoi les concepteurs Java ont créé des champs dans une interface static et final?

90
peakit

Une interface ne peut pas avoir un comportement ou un état car elle est conçue pour spécifier uniquement un contrat d'interaction, pas de détails d'implémentation. Aucun comportement n'est imposé en n'autorisant pas les corps de méthode/constructeur ni les blocs d'initialisation static/instance. Aucun état n'est imposé en autorisant uniquement les champs finaux statiques. Par conséquent, la classe peut avoir un état (état statique), mais l'état de l'instance n'est pas déduit 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).

119
Adriaan Koster

RAISON D'ÊTRE final

Toute implémentation peut changer la valeur des champs si elles ne sont pas définies en tant que final. Ensuite, ils deviendraient une partie de la mise en œuvre. Une interface est une spécification pure sans aucune implémentation.

RAISON D'ÊTRE static

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

24

Il y a quelques points passés sous silence ici:

Le fait que les champs d’une interface soient implicitement finaux ne signifie pas qu’ils doivent être des constantes au moment de la compilation, ou même immuables. Vous pouvez définir par exemple.

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

(Attention, ceci dans une définition d'annotation peut confuse javac , en raison du fait que ce qui précède est compilé en un initialiseur statique.)

De plus, la raison de cette restriction est plus stylistique que technique, et beaucoup de gens aimeraient bien { aimeraient la voir détendue .

16
Jesse Glick

Les champs doivent être statiques car ils ne peuvent pas être abstraits (comme les méthodes peuvent). Parce qu'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 ils peuvent être accédés par de nombreux implémenteurs différents, ce qui peut être problématique (leur synchronisation). Aussi pour éviter qu'il soit ré-implémenté (caché).

Juste ma pensée.

9
NawaMan

Je considère que l'exigence que les champs soient définitifs est indûment restrictive et constitue une erreur des concepteurs du langage Java. Il y a des moments, par exemple gestion de l'arborescence, lorsque vous devez définir des constantes dans l'implémentation nécessaires pour effectuer des opérations sur un objet du type 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 à la mettre en œuvre en renvoyant un littéral:

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

Cependant, il serait plus simple, plus clair et moins sujet aux implémentations aberrantes d’utiliser cette syntaxe:

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

Spécification, contrats ... L'instruction machine pour l'accès aux champs utilise l'adresse de l'objet plus le décalage du champ. Comme les classes peuvent implémenter de nombreuses interfaces, il n’existe aucun moyen de créer un champ d’interface non final ayant le même décalage dans toutes les classes qui étendent cette interface. Par conséquent, un mécanisme différent pour l'accès au champ doit être implémenté: deux accès mémoire (obtenir le décalage du champ, obtenir la valeur du champ) au lieu d'un et maintenir le type de table de champ virtuel (analogue de la table de méthode virtuelle). J'imagine qu'ils ne voulaient tout simplement pas compliquer JVM par des fonctionnalités faciles à simuler via des éléments existants (méthodes).

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

0
Yaroslav