web-dev-qa-db-fra.com

Quelle est la raison de Java.lang.IllegalArgumentException: pas de classe const enum, même si itérer via values ​​() fonctionne correctement?

Cette question est essentiellement une extension de mon question précédente . J'ai posé la question précédente pour m'assurer que les constantes Enum sont renseignées lors du chargement de la classe. Voici à nouveau ma classe avec l’ajout d’une méthode simple getByName:

public enum PropName {

  CONTENTS("contents"),
  USE_QUOTES("useQuotes"),
  ONKEYDOWN("onkeydown"),
  BROWSER_ENTIRE_TABLE("browseEntireTable"),
  COLUMN_HEADINGS("columnHeadings"),
  PAGE_SIZE("pageSize"),
  POPUP_TITLE("popupTitle"),
  FILTER_COL("filterCol"),
  SQL_SELECT("sqlSelect"),
  ;

  private String name;

  private PropName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public static PropName getByName(String name){
    return   PropName.valueOf(name);
  }
}

Un appel à la méthode getByName("columnHeadings") renvoie Java.lang.IllegalArgumentException: No enum const class labware.web.component.limsgrid.PropName.columnHeadings, Mais si je remplace cette méthode par le code suivant, cela fonctionne.

 public static PropName getByName(String name){
    for(PropName prop : values()){
      if(prop.getName().equals(name)){
        return prop;
      }
    }

    throw new IllegalArgumentException(name + " is not a valid PropName");
  }

Des idées quant à ce que je fais mal ici?

42
Geek

Enum.valueOf() ne vérifie que le nom de la constante, vous devez donc le transmettre "COLUMN_HEADINGS" au lieu de "columnHeadings". Votre propriété name n'a rien à voir avec les éléments internes d'Enum.


Pour répondre aux questions/préoccupations dans les commentaires:

La méthode "intégrée" de l'énumération (déclarée implicitement) valueOf(String name) va rechercher une constante d'énumération portant ce nom exact. Si votre entrée est "columnHeadings", vous avez au moins trois choix:

  1. Oubliez les conventions de nommage pour un peu et nommez simplement vos constantes car cela a du sens: enum PropName { contents, columnHeadings, ...}. C'est évidemment le plus pratique.
  2. Convertissez votre entrée camelCase en UPPER_SNAKE_CASE avant d'appeler valueOf, si vous êtes vraiment friand de conventions de dénomination.
  3. Implémentez votre propre méthode de recherche à la place de la commande intégrée valueOf pour rechercher la constante correspondante pour une entrée. Cela a plus de sens s'il existe plusieurs mappages possibles pour le même ensemble de constantes.
66
Costi Ciudatu

C'est parce que vous avez défini votre propre version de name pour votre enum et que getByName ne l'utilise pas.

getByName("COLUMN_HEADINGS") fonctionnerait probablement.

10
Guillaume

Au lieu de définir: COLUMN_HEADINGS("columnHeadings")

Essayez de le définir comme suit: COLUMNHEADINGS("columnHeadings")

Ensuite, lorsque vous appelez getByName(String name) method, appelez-le avec la chaîne en majuscule comme ceci: getByName(myStringVariable.toUpperCase())

J'ai eu le même problème que vous et cela a fonctionné pour moi.

2
LuvCode