92 votes

Pourquoi aucune méthode statique dans les interfaces, mais des champs statiques et des classes internes OK? [avant Java8]

Il y a eu quelques questions posées ici sur pourquoi vous ne pouvez pas définir de méthodes statiques dans les interfaces, mais aucune d'entre elles n'aborde une incohérence fondamentale : pourquoi peut-on définir des champs statiques et des types internes statiques dans une interface, mais pas des méthodes statiques ?

Les types internes statiques ne sont peut-être pas une comparaison équitable, car il s'agit simplement de sucre syntaxique qui génère une nouvelle classe, mais pourquoi des champs mais pas des méthodes ?

Un argument contre les méthodes statiques dans les interfaces est que cela casse la stratégie de résolution de la table virtuelle utilisée par la JVM, mais cela ne devrait-il pas s'appliquer de manière égale aux champs statiques, c'est-à-dire que le compilateur peut simplement l'incorporer ?

La cohérence est ce que je recherche, et Java aurait dû soit ne pas supporter de statiques sous aucune forme dans une interface, soit être cohérent et les autoriser.

0 votes

Les champs sont définis alors que la méthode n'a pas de corps. Tenter d'appeler la méthode provoquera une erreur, tandis que les variables seront toujours présentes : qu'elles soient par défaut ou définies.

1 votes

bugs.sun.com/view_bug.do?bug_id=4093687 - fermé ne sera pas fixé avec plus de 200 votes, et c'était en 1997...

0 votes

@erickson - pourquoi dis-tu que c'est une réponse échouant à une interview ?

3voto

toolkit Points 27248

Avant Java 5, une utilisation courante des champs statiques était :

interface HtmlConstants {
    static String OPEN = "<";
    static String SLASH_OPEN = "</";
    static String CLOSE = ">";
    static String SLASH_CLOSE = " />";
    static String HTML = "html";
    static String BODY = "body";
    ...
}

public class HtmlBuilder implements HtmlConstants { // implements ?!?
    public String buildHtml() {
       StringBuffer sb = new StringBuffer();
       sb.append(OPEN).append(HTML).append(CLOSE);
       sb.append(OPEN).append(BODY).append(CLOSE);
       ...
       sb.append(SLASH_OPEN).append(BODY).append(CLOSE);
       sb.append(SLASH_OPEN).append(HTML).append(CLOSE);
       return sb.toString();
    }
}

Cela signifiait que HtmlBuilder n'aurait pas à qualifier chaque constante, il pouvait donc utiliser OPEN au lieu de HtmlConstants.OPEN

L'utilisation de implements de cette manière est finalement confuse.

Maintenant avec Java 5, nous avons la syntaxe import static pour obtenir le même effet :

private final class HtmlConstants {
    ...
    private HtmlConstants() { /* empty */ }
}

import static HtmlConstants.*;
public class HtmlBuilder { // n'utilise plus implements
    ...
}

3voto

En fait, parfois il y a des raisons pour lesquelles quelqu'un peut bénéficier des méthodes statiques. Elles peuvent être utilisées comme des méthodes de fabrique pour les classes qui implémentent l'interface. Par exemple, c'est la raison pour laquelle nous avons maintenant l'interface Collection et la classe Collections dans openjdk. Donc il y a des solutions de contournement comme toujours - fournir une autre classe avec un constructeur privé qui servira de "namespace" pour les méthodes statiques.

3voto

Angel O'Sphere Points 1469

Il n'y a pas de réelle raison pour ne pas avoir de méthodes statiques dans les interfaces, sauf : les concepteurs du langage Java n'en ont pas voulu ainsi. D'un point de vue technique, il serait logique de les autoriser. Après tout, une classe abstraite peut en avoir. Je suppose, mais je ne l'ai pas testé, que vous pouvez "fabriquer" du code octet où l'interface a une méthode statique et cela devrait selon moi fonctionner sans problème pour appeler la méthode et/ou utiliser l'interface comme d'habitude.

2voto

Vasil Points 11172

Je me demande souvent pourquoi des méthodes statiques après tout? Ils ont leur utilité, mais les méthodes au niveau du package/namespace couvriraient probablement 80 de ce pour quoi les méthodes statiques sont utilisées.

1voto

Eli Courtwright Points 53071

Deux raisons principales viennent à l'esprit :

  1. Les méthodes statiques en Java ne peuvent pas être redéfinies par les sous-classes, et c'est bien plus problématique pour les méthodes que pour les champs statiques. En pratique, je n'ai jamais eu envie de redéfinir un champ dans une sous-classe, mais je redéfinis des méthodes tout le temps. Ainsi, le fait d'avoir des méthodes statiques empêche une classe implémentant l'interface de fournir sa propre implémentation de cette méthode, ce qui annule largement l'intérêt d'utiliser une interface.

  2. Les interfaces ne sont pas censées contenir du code; c'est ce pour quoi les classes abstraites sont faites. L'objectif principal d'une interface est de vous permettre de parler d'objets potentiellement non liés qui ont tous un certain ensemble de méthodes. Fournir une implémentation de ces méthodes va au-delà de ce que les interfaces sont censées être.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X