web-dev-qa-db-fra.com

Pourquoi ne puis-je pas définir une méthode statique dans une interface Java?

EDIT: À partir de Java 8, les méthodes statiques sont désormais autorisées dans les interfaces.

Voici l'exemple:

public interface IXMLizable<T>
{
  static T newInstanceFromXML(Element e);
  Element toXMLElement();
}

Bien sûr ça ne marchera pas. Mais pourquoi pas?

Un des problèmes possibles serait ce qui se passe lorsque vous appelez:

IXMLizable.newInstanceFromXML(e);

Dans ce cas, je pense que cela devrait simplement appeler une méthode vide (c'est-à-dire {}). Toutes les sous-classes seraient obligées d'implémenter la méthode statique, ainsi elles iraient bien si elles appelaient la méthode statique. Alors pourquoi n'est-ce pas possible?

EDIT: Je suppose que je cherche une réponse plus profonde que "parce que c'est ainsi que Java est".

Y a-t-il une raison technologique particulière pour laquelle les méthodes statiques ne peuvent pas être écrasées? Autrement dit, pourquoi les concepteurs de Java ont-ils décidé de rendre les méthodes d'instance remplaçables, mais non les méthodes statiques?

EDIT: Le problème de ma conception est que j'essaie d'utiliser des interfaces pour appliquer une convention de codage.

C'est-à-dire que le but de l'interface est double:

  1. Je veux que l'interface IXMLizable me permette de convertir les classes qui l'implémentent en éléments XML (en utilisant le polymorphisme, ça fonctionne bien).

  2. Si quelqu'un veut créer une nouvelle instance d'une classe qui implémente l'interface IXMLizable, il saura toujours qu'il y aura un constructeur statique newInstanceFromXML (Element e).

Existe-t-il un autre moyen de s’assurer de cela, mis à part l’ajout d’un commentaire dans l’interface?

473
cdmckay

Java 8 autorise les méthodes d'interface statique

Avec Java 8, les interfaces peuvent avoir des méthodes statiques. Ils peuvent également avoir des méthodes d'instance concrètes, mais pas des champs d'instance.

Il y a vraiment deux questions ici:

  1. Pourquoi, dans le mauvais vieux temps, les interfaces ne pouvaient-elles pas contenir de méthodes statiques?
  2. Pourquoi les méthodes statiques ne peuvent-elles pas être remplacées?

Méthodes statiques dans les interfaces

Il n'y avait aucune raison technique forte pour laquelle les interfaces ne pouvaient pas avoir de méthodes statiques dans les versions précédentes. Ceci est résumé joliment par l’affiche d’une question en double. Les méthodes d’interface statique étaient initialement considérées comme n petit changement de langue, puis il y avait ne proposition officielle pour les ajouter dans Java 7, mais ce fut plus tard abandonné en raison de complications imprévues.

Enfin, Java 8 a introduit les méthodes d'interface statique, ainsi que les méthodes d'instance remplaçables avec une implémentation par défaut. Cependant, ils ne peuvent toujours pas avoir de champs d'instance. Ces fonctionnalités font partie du support d’expression lambda, et vous en saurez plus à ce sujet dans Partie H de JSR 335.

Ignorer les méthodes statiques

La réponse à la deuxième question est un peu plus compliquée.

Les méthodes statiques peuvent être résolues au moment de la compilation. La répartition dynamique a du sens pour les méthodes d'instance, où le compilateur ne peut pas déterminer le type concret de l'objet et ne peut donc pas résoudre la méthode à invoquer. Mais appeler une méthode statique nécessite une classe, et puisque cette classe est connue de manière statique - au moment de la compilation - l'envoi dynamique n'est pas nécessaire.

Un peu de contexte sur le fonctionnement des méthodes d'instance est nécessaire pour comprendre ce qui se passe ici. Je suis sûr que la mise en œuvre réelle est assez différente, mais laissez-moi expliquer ma notion de répartition de méthode, qui modélise avec précision le comportement observé.

Supposez que chaque classe a une table de hachage qui mappe les signatures de méthode (nom et types de paramètre) à un bloc de code réel pour implémenter la méthode. Lorsque la machine virtuelle tente d'appeler une méthode sur une instance, elle interroge l'objet de sa classe et recherche la signature demandée dans la table de la classe. Si un corps de méthode est trouvé, il est appelé. Sinon, la classe parente de la classe est obtenue et la recherche y est répétée. Cela se poursuit jusqu'à ce que la méthode soit trouvée ou qu'il n'y ait plus de classes parentes, ce qui donne un NoSuchMethodError.

Si une superclasse et une sous-classe ont toutes les deux une entrée dans leurs tables pour la même signature de méthode, la version de la sous-classe est rencontrée en premier et la version de la superclasse n'est jamais utilisée - il s'agit d'un "remplacement".

Supposons maintenant que nous ignorions l'instance d'objet et que nous commencions avec une sous-classe. La résolution pourrait procéder comme ci-dessus, vous donnant une sorte de méthode statique "remplaçable". Cependant, la résolution peut se produire à la compilation, car le compilateur commence à partir d'une classe connue, plutôt que d'attendre le moment de l'exécution pour interroger un objet d'un type non spécifié pour sa classe. Il est inutile de "surcharger" une méthode statique, car on peut toujours spécifier la classe qui contient la version souhaitée.


Constructeur "interfaces"

Voici un peu plus de matière pour aborder la récente modification de la question.

Il semble que vous souhaitiez obliger efficacement une méthode de type constructeur pour chaque implémentation de IXMLizable. Oubliez d'essayer d'imposer cela avec une interface pendant une minute et supposez que certaines classes répondent à cette exigence. Comment l'utiliseriez-vous?

class Foo implements IXMLizable<Foo> {
  public static Foo newInstanceFromXML(Element e) { ... }
}

Foo obj = Foo.newInstanceFromXML(e);

Etant donné que vous devez nommer explicitement le type concret Foo lors de la "construction" du nouvel objet, le compilateur peut vérifier qu'il dispose bien de la méthode factory nécessaire. Et si ça ne marche pas, et alors? Si je peux implémenter une IXMLizable sans le "constructeur", créer une instance et la transmettre à votre code, elle est une IXMLizable avec toutes les interfaces nécessaires.

La construction fait partie de la mise en oeuvre, pas l'interface. Tout code qui fonctionne correctement avec l'interface ne se soucie pas du constructeur. N'importe quel code qui se soucie du constructeur a besoin de connaître le type concret de toute façon, et l'interface peut être ignorée.

494
erickson

Cela a déjà été demandé et répondu, ici

Pour dupliquer ma réponse:

Il n'est jamais inutile de déclarer une méthode statique dans une interface. Ils ne peuvent pas être exécutés par l'appel normal MyInterface.staticMethod (). Si vous les appelez en spécifiant la classe d'implémentation MyImplementor.staticMethod (), vous devez connaître la classe réelle, il est donc indifférent que l'interface le contienne ou non.

Plus important encore, les méthodes statiques ne sont jamais remplacées, et si vous essayez de le faire:

MyInterface var = new MyImplementingClass();
var.staticMethod();

les règles pour static indiquent que la méthode définie dans le type déclaré de var doit être exécutée. Puisque c'est une interface, c'est impossible.

Si vous ne pouvez pas exécuter "result = MyInterface.staticMethod ()", vous devez exécuter la version de la méthode définie dans MyInterface. Mais il ne peut y avoir de version définie dans MyInterface, car c'est une interface. Il n'a pas de code par définition.

Bien que vous puissiez dire que cela revient à "car Java le fait ainsi", en réalité, la décision est une conséquence logique d'autres décisions de conception, également prises pour une très bonne raison.

47
DJClayworth

Normalement, cela se fait en utilisant un motif Factory

public interface IXMLizableFactory<T extends IXMLizable> {
  public T newInstanceFromXML(Element e);
}

public interface IXMLizable {
  public Element toXMLElement();
}
37
Peter Lawrey

Avec l'avènement de Java 8 , il est maintenant possible d'écrire default et static méthodes dans l'interface. docs.Oracle/staticMethod

Par exemple:

public interface Arithmetic {

    public int add(int a, int b);

    public static int multiply(int a, int b) {
        return a * b;
    }
}
public class ArithmaticImplementation implements Arithmetic {

    @Override
    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int result = Arithmetic.multiply(2, 3);
        System.out.println(result);
    }
}

Résultat : 6

CONSEIL: L'appel d'une méthode d'interface statique ne nécessite pas d'être implémenté par une classe. Cela se produit sûrement parce que les mêmes règles que les méthodes statiques des superclasses s'appliquent aux méthodes statiques des interfaces.

34
rogue lad

Les méthodes statiques ne pouvant pas être remplacées dans des sous-classes, elles ne peuvent donc pas être abstraites. Et toutes les méthodes d'une interface sont, de facto, abstraites.

21
Michael Myers

Pourquoi ne puis-je pas définir une méthode statique dans une interface Java?

En fait, vous pouvez utiliser Java 8.

Selon Java doc :

Une méthode statique est une méthode associée à la classe dans laquelle elle est définie plutôt qu'à un objet. Chaque instance de la classe partage ses méthodes statiques

Dans Java 8, une interface peut avoir des méthodes par défaut et des méthodes statiques . Cela nous permet d’organiser plus facilement des méthodes d’aide dans nos bibliothèques. Nous pouvons garder les méthodes statiques spécifiques à une interface dans la même interface plutôt que dans une classe séparée.

Exemple de méthode par défaut:

list.sort(ordering);

au lieu de

Collections.sort(list, ordering);

Exemple de méthode statique (de doc lui-même):

public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default public ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }    
}
10
i_am_zero

Premièrement, toutes les décisions linguistiques sont des décisions prises par les créateurs de langues. Rien dans le monde du génie logiciel ou de la définition de langage ou de l'écriture de compilateur/interprète ne permet d'affirmer qu'une méthode statique ne peut pas faire partie d'une interface. J'ai créé quelques langages et écrit des compilateurs pour ceux-ci - il ne s'agit que de rester assis et de définir une sémantique significative. Je dirais que la sémantique d'une méthode statique dans une interface est remarquablement claire, même si le compilateur doit différer la résolution de la méthode au moment de l'exécution.

Deuxièmement, le fait d’utiliser des méthodes statiques signifie qu’il existe une raison valable d’avoir un modèle d’interface incluant des méthodes statiques - je ne peux parler pour aucun d’entre vous, mais j’utilise régulièrement des méthodes statiques.

La réponse correcte la plus probable est qu'il n'y avait aucun besoin perçu, au moment de la définition du langage, d'utiliser des méthodes statiques dans les interfaces. Java a beaucoup évolué au fil des ans et cet élément a apparemment suscité un certain intérêt. Le fait qu’il ait été examiné Java 7 indique que son niveau d’intérêt pourrait entraîner un changement de langue. Pour ma part, je serai heureux lorsque je n'aurai plus besoin d'instancier un objet pour pouvoir appeler ma méthode getter non statique afin d'accéder à une variable statique dans une instance de sous-classe ...

6
tallgirl

Les interfaces sont concernées par le polymorphisme qui est intrinsèquement lié aux instances d'objet, pas aux classes. Par conséquent, statique n'a pas de sens dans le contexte d'une interface.

6
cliff.meyers
  • "Y a-t-il une raison particulière pour que les méthodes statiques ne puissent pas être remplacées".

Permettez-moi de reformuler cette question pour vous en complétant les définitions.

  • "Y a-t-il une raison particulière pour laquelle les méthodes résolues au moment de la compilation ne peuvent pas être résolues au moment de l'exécution."

Si je veux appeler une méthode sans instance, mais connaissant la classe, comment puis-je la résoudre en fonction d'une instance que je n'ai pas?.

5
Darron

Les méthodes statiques ne sont pas virtuelles comme les méthodes d'instance, je suppose donc que les concepteurs de Java ont décidé de ne pas les utiliser dans les interfaces.

Mais vous pouvez placer des classes contenant des méthodes statiques dans des interfaces. Tu pourrais essayer ça!

public interface Test {
    static class Inner {
        public static Object get() {
            return 0;
        }
    }
}
5
Adrian Pronk

Commenter EDIT: As of Java 8, static methods are now allowed in interfaces.

C'est vrai, les méthodes statiques depuis Java 8 sont autorisées dans les interfaces, mais votre exemple ne fonctionne toujours pas. Vous ne pouvez pas simplement définir une méthode statique: vous devez l’implémenter ou vous obtiendrez une erreur de compilation.

3
flavio

Eh bien, sans génériques, les interfaces statiques sont inutiles car tous les appels de méthodes statiques sont résolus au moment de la compilation. Donc, ils ne servent vraiment à rien.

Avec les génériques, ils ont l'utilisation - avec ou sans implémentation par défaut. De toute évidence, il faudrait qu'il y ait une priorité, etc. Cependant, j’imagine qu’un tel usage n’était pas très OO (comme le soulignent les autres réponses, obtus), et qu’il n’était donc pas considéré comme méritant l’effort nécessaire pour les implémenter utilement.

2
MichaelGG

Plusieurs réponses ont abordé les problèmes liés au concept de méthodes statiques pouvant être remplacées. Cependant, il arrive parfois que vous rencontriez un modèle qui semble correspondre exactement à ce que vous souhaitez utiliser.

Par exemple, je travaille avec un calque relationnel-objet contenant des objets de valeur, mais également des commandes permettant de manipuler les objets de valeur. Pour diverses raisons, chaque classe d'objets de valeur doit définir des méthodes statiques permettant au framework de rechercher l'instance de commande. Par exemple, pour créer une personne, vous feriez:

cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();

et pour charger une personne par ID que vous feriez

cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();

C'est assez pratique, mais cela pose des problèmes. notamment l'existence de méthodes statiques ne peut pas être imposée dans l'interface. Une méthode statique remplaçable dans l'interface serait exactement ce dont nous aurions besoin, si seulement cela pouvait fonctionner d'une manière ou d'une autre.

Les EJB résolvent ce problème en ayant une interface Home; chaque objet sait comment trouver son Home et le Home contient les méthodes "statiques". De cette façon, les méthodes "statiques" peuvent être remplacées si nécessaire, et vous n'encombrez pas l'interface normale (appelée "Remote") avec des méthodes qui ne s'appliquent pas à une instance de votre bean. Il suffit de faire en sorte que l'interface normale spécifie une méthode "getHome ()". Renvoie une instance de l'objet Home (qui peut être un singleton, je suppose) et l'appelant peut effectuer des opérations qui affectent tous les objets Person.

2
Why can't I define a static method in a Java interface?

Toutes les méthodes d'une interface sont explicitement abstraites et vous ne pouvez donc pas les définir comme statiques, car les méthodes statiques ne peuvent pas être abstraites.

2
Aniket Thakur

Une interface ne peut jamais être déréférencée statiquement, par ex. ISomething.member. Une interface est toujours déréférencée via une variable qui fait référence à une instance d'une sous-classe de l'interface. Ainsi, une référence d'interface ne peut jamais savoir à quelle sous-classe elle se réfère sans une instance de sa sous-classe.

Ainsi, l’approximation la plus proche d’une méthode statique dans une interface serait une méthode non statique qui ignore "ceci", c’est-à-dire qu’elle n’accède à aucun membre non statique de l’instance. En abstraction de bas niveau, chaque méthode non statique (après recherche dans une table quelconque) est en réalité simplement une fonction avec une étendue de classe qui prend "ceci" comme paramètre formel implicite. Voir objet singleton de Scala et interopérabilité avec Java comme preuve de ce concept. Et ainsi chaque méthode statique est une fonction avec une portée de classe qui ne prend pas un paramètre "this". Ainsi, normalement, une méthode statique peut être appelée de manière statique, mais comme indiqué précédemment, une interface n'a aucune implémentation (est abstraite).

Ainsi, pour obtenir une approximation la plus proche d'une méthode statique dans une interface, vous devez utiliser une méthode non statique et ne pas accéder à aucun des membres d'instance non statiques. Il n'y aurait aucun autre avantage possible en termes de performances, car il n'y a aucun moyen de lier statiquement (au moment de la compilation) une ISomething.member(). Le seul avantage que je vois d’une méthode statique dans une interface est qu’elle ne saisirait pas (c’est-à-dire ignorer) un "ceci" implicite et interdirait donc l’accès à aucun des membres d’instance non statiques. Cela déclarerait implicitement que la fonction qui n'accède pas à "this" est immutate et même en lecture seule par rapport à sa classe contenante. Mais une déclaration "statique" dans une interface ISomething pourrait également dérouter les personnes qui ont essayé d'y accéder avec ISomething.member(), ce qui provoquerait une erreur du compilateur. Je suppose que si l'erreur du compilateur était suffisamment explicative, ce serait mieux que d'essayer d'éduquer les gens sur l'utilisation d'une méthode non statique pour accomplir ce qu'ils veulent (apparemment principalement des méthodes d'usine), comme nous le faisons ici (et cela a été répété 3 Q & A fois sur ce site), il s’agit donc d’un problème qui n’est pas intuitif pour beaucoup de gens. J'ai dû y réfléchir pendant un moment pour bien comprendre.

Pour obtenir un champ statique modifiable dans une interface, utilisez des méthodes non statiques getter et setter dans une interface, afin d'accéder à ce champ statique situé dans la sous-classe. Sidenote, la statique apparemment immuable peut être déclarée dans une interface Java avec static final.

1
Shelby Moore III

Un élément pouvant être implémenté est l'interface statique (au lieu de la méthode statique dans une interface). Toutes les classes implémentant une interface statique donnée doivent implémenter les méthodes statiques correspondantes. Vous pouvez obtenir une interface statique SI à partir de n’importe quelle classe Clazz en utilisant

SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null

alors vous pouvez appeler si.method(params). Cela serait utile (pour un modèle de conception d'usine par exemple) car vous pouvez obtenir (ou vérifier l'implémentation de) des méthodes statiques SI implémentées à partir d'une classe de compilation inconnue! Une répartition dynamique est nécessaire et vous pouvez remplacer les méthodes statiques (si elles ne sont pas définitives) d'une classe en l'étendant (lorsqu'elle est appelée via l'interface statique). Bien entendu, ces méthodes ne peuvent accéder qu'aux variables statiques de leur classe.

0

Supposons que les méthodes statiques soient autorisées dans les interfaces: * Elles forceraient toutes les classes implémentées à déclarer cette méthode. * Les interfaces sont généralement utilisées à travers des objets. Par conséquent, les seules méthodes efficaces sont les méthodes non statiques. * Toute classe connaissant une interface particulière peut invoquer ses méthodes statiques. Par conséquent, la méthode statique d'une classe mettant en œuvre serait appelée dessous, mais la classe invocateur ne sait pas laquelle. Comment le savoir? Il n'y a pas d'instanciation pour deviner ça!

Les interfaces ont été pensées pour être utilisées lors de travaux avec des objets. De cette façon, un objet est instancié à partir d'une classe particulière, ce qui résout ce dernier problème. La classe appelante n'a pas besoin de savoir quelle classe particulière est car l'instanciation peut être effectuée par une troisième classe. Donc, la classe appelante ne connait que l'interface.

Si nous voulons que cela soit étendu aux méthodes statiques, nous devrions avoir la possibilité de spécifier une classe d'implémentation avant, puis de passer une référence à la classe invoquante. Cela pourrait utiliser la classe via les méthodes statiques de l'interface. Mais quelle est la différence entre cette référence et un objet? Nous avons juste besoin d'un objet représentant ce que c'était la classe. Désormais, l'objet représente l'ancienne classe et pourrait implémenter une nouvelle interface incluant les anciennes méthodes statiques - celles-ci sont désormais non statiques.

Les métaclasses servent à cette fin. Vous pouvez essayer la classe Class of Java. Mais le problème est que Java n'est pas assez flexible pour cela. Vous ne pouvez pas déclarer une méthode dans l'objet de classe d'une interface.

Ceci est un problème de méta - quand vous devez faire le cul

..blah blah

de toute façon, vous avez une solution de contournement facile - rendre la méthode non statique avec la même logique. Mais vous devez d'abord créer un objet pour appeler la méthode.

0
beibichunai

Les interfaces fournissent simplement une liste des éléments qu'une classe fournira, et non une implémentation réelle de ces éléments, qui correspond à votre élément statique.

Si vous voulez des statiques, utilisez une classe abstraite et héritez-la, sinon, supprimez la statique.

J'espère que ça t'as aidé!

0
samoz

Alors que je réalisais que Java 8 résolvait ce problème, je pensais que je devrais ajouter un scénario sur lequel je suis en train de travailler (verrouillé pour utiliser Java 7), où il est possible de spécifier des paramètres statiques. méthodes dans une interface serait utile.

J'ai plusieurs définitions d'enum où j'ai défini les champs "id" et "displayName" ainsi que des méthodes d'assistance évaluant les valeurs pour diverses raisons. L'implémentation d'une interface me permet de m'assurer que les méthodes getter sont en place, mais pas les méthodes d'assistance statique. Étant une énumération, il n’existe vraiment aucun moyen propre de décharger les méthodes auxiliaires dans une classe abstraite héritée ou quelque chose de similaire, de sorte que les méthodes doivent être définies dans l’énumération elle-même. De plus, comme il s'agit d'une énumération, vous ne pourrez jamais le transmettre en tant qu'objet instancié et le traiter comme un type d'interface, mais pouvoir exiger l'existence de méthodes d'assistance statique via une interface est ce qui me plaît le plus il est supporté dans Java 8.

Voici le code illustrant mon propos.

Définition de l'interface:

public interface IGenericEnum <T extends Enum<T>> {
    String getId();
    String getDisplayName();
    //If I was using Java 8 static helper methods would go here
}

Exemple de définition d'une énumération:

public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
    STANDARD ("Standard", "Standard Mode"),
    DEBUG ("Debug", "Debug Mode");

    String id;
    String displayName;

    //Getter methods
    public String getId() {
        return id;
    }

    public String getDisplayName() {
        return displayName;
    }

    //Constructor
    private ExecutionModeType(String id, String displayName) {
        this.id = id;
        this.displayName = displayName;
    }

    //Helper methods - not enforced by Interface
    public static boolean isValidId(String id) {
        return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
    }

    public static String printIdOptions(String delimiter){
        return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
    }

    public static String[] getIdArray(){
        return GenericEnumUtility.getIdArray(ExecutionModeType.class);
    }

    public static ExecutionModeType getById(String id) throws NoSuchObjectException {
        return GenericEnumUtility.getById(ExecutionModeType.class, id);
    }
}

Définition de l'utilitaire enum générique:

public class GenericEnumUtility {
    public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {       
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(enumOption.getId().equals(id)) {
                return true;
            }
        }

        return false;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
        String ret = "";
        delimiter = delimiter == null ? " " : delimiter;

        int i = 0;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(i == 0) {
                ret = enumOption.getId();
            } else {
                ret += delimiter + enumOption.getId();
            }           
            i++;
        }

        return ret;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
        List<String> idValues = new ArrayList<String>();

        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            idValues.add(enumOption.getId());
        }

        return idValues.toArray(new String[idValues.size()]);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
        id = id == null ? "" : id;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(id.equals(enumOption.getId())) {
                return (T)enumOption;
            }
        }

        throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
    }
}
0
Ryan

Vous ne pouvez pas définir de méthodes statiques dans une interface car les méthodes statiques appartiennent à une classe et non à une instance de classe, et les interfaces ne sont pas des classes. Lire la suite ici.

Cependant, si vous le souhaitez, vous pouvez le faire:

public class A {
  public static void methodX() {
  }
}

public class B extends A {
  public static void methodX() {
  }
}

Dans ce cas, vous avez deux classes avec deux méthodes statiques distinctes appelées methodX ().

0
Handerson

Supposons que vous puissiez le faire. Considérons cet exemple:

interface Iface {
  public static void thisIsTheMethod();
}

class A implements Iface {

  public static void thisIsTheMethod(){
    system.out.print("I'm class A");
  }

}

class B extends Class A {

  public static void thisIsTheMethod(){
    System.out.print("I'm class B");
  } 
}

SomeClass {

  void doStuff(Iface face) {
    IFace.thisIsTheMethod();
    // now what would/could/should happen here.
  }

}
0
pvgoddijn

Pour résoudre ceci: erreur: corps de méthode manquant, ou déclarer un résumé abstrait statique statique principal (String [] args);

interface I
{
    int x=20;
    void getValue();
    static void main(String[] args){};//Put curly braces 
}
class InterDemo implements I
{
    public void getValue()
    {
    System.out.println(x);
    }
    public static void main(String[] args)
    {
    InterDemo i=new InterDemo();
    i.getValue();   
    }

}

sortie: 20

Maintenant, nous pouvons utiliser la méthode statique dans l'interface

0
Aashish Pawar