64 votes

Java : Enum et Int.

Lorsque l'on utilise des drapeaux en Java, j'ai vu deux approches principales. L'une utilise des valeurs int et une ligne d'instructions if-else. L'autre consiste à utiliser des enums et des instructions de changement de cas.

Je me demandais s'il y avait une différence en termes d'utilisation de la mémoire et de vitesse entre l'utilisation des enums et des ints pour les drapeaux ?

132voto

Bohemian Points 134107

Les deux sites ints y enums peut utiliser à la fois switch ou if-then-else, et l'utilisation de la mémoire est également minimale pour les deux, et la vitesse est similaire - il n'y a pas de différence significative entre eux sur les points que vous avez soulevés.

Cependant, la différence la plus importante est la vérification des types. Enums sont vérifiés, ints ne le sont pas.

Considérez ce code :

public class SomeClass {
    public static int RED = 1;
    public static int BLUE = 2;
    public static int YELLOW = 3;
    public static int GREEN = 3; // sic

    private int color;

    public void setColor(int color) {
        this.color = color;
    }   
}

Alors que de nombreux clients l'utiliseront correctement,

new SomeClass().setColor(SomeClass.RED);

Rien ne les empêche d'écrire cela :

new SomeClass().setColor(999);

Il y a trois problèmes principaux avec l'utilisation du public static final modèle :

  • Le problème se produit à temps de fonctionnement pas compiler temps, donc ça va être plus cher à réparer, et plus difficile de trouver la cause.
  • Vous devez écrire du code pour gérer les mauvaises entrées - typiquement un if-then-else avec une finale else throw new IllegalArgumentException("Unknown color " + color); - encore cher
  • Rien n'empêche une collision des constantes - le code de la classe ci-dessus compilera même si YELLOW y GREEN les deux ont la même valeur 3

Si vous utilisez enums vous abordez tous ces problèmes :

  • Votre code ne sera pas compilé si vous ne passez pas des valeurs valides dans les champs
  • Pas besoin d'un code spécial "mauvaise entrée" - le compilateur s'en charge pour vous.
  • Les valeurs des Enum sont uniques

12voto

duffymo Points 188155

L'utilisation de la mémoire et la vitesse ne sont pas les considérations qui comptent. Vous ne seriez pas en mesure de mesurer une différence dans un sens ou dans l'autre.

Je pense que les enums devraient être préférés lorsqu'ils s'appliquent, car ils mettent l'accent sur le fait que les valeurs choisies vont ensemble et constituent un ensemble fermé. La lisibilité est également grandement améliorée. Le code utilisant les enums est plus auto-documenté que les valeurs int éparpillées dans le code.

Préférez les enums.

12voto

the-banana-king Points 391

Vous pouvez même utiliser les Enums pour remplacer ces drapeaux combinés par bit, par exemple int flags = FLAG_1 | FLAG_2;

Au lieu de cela, vous pouvez utiliser un typeafe EnumSet :

Set<FlagEnum> flags = EnumSet.of(FlagEnum.FLAG_1, FlagEnum.FLAG_2);

// then simply test with contains()
if(flags.contains(FlagEnum.FLAG_1)) ...

La documentation indique que ces classes sont optimisées en interne comme des vecteurs de bits et que l'implémentation devrait être suffisamment performante pour remplacer les drapeaux basés sur des int.

7voto

Tim Points 3652

L'une des raisons pour lesquelles vous verrez du code utiliser int au lieu d'un enum c'est que Java n'avait pas d'enums avant Java 1.5.

Ainsi, si vous regardez un code écrit à l'origine pour une ancienne version de Java, alors l'option int était la seule option disponible.

Il y a un très petit nombre d'endroits où l'on utilise int est toujours préférable dans le code Java moderne, mais dans la plupart des cas, il est préférable d'utiliser un drapeau de type enum en raison de la sécurité et de l'expressivité qu'ils offrent.

En termes d'efficacité, cela dépendra de la manière exacte dont ils sont utilisés. La JVM traite les deux types de manière très efficace, mais la méthode int serait probablement légèrement plus efficace dans certains cas d'utilisation (parce qu'ils sont traités comme des primitifs plutôt que comme des objets), mais dans d'autres cas, l'enum serait plus efficace (parce qu'elle n'a pas besoin de passer par le boxing/unboxing).

Il serait difficile de trouver une situation dans laquelle la différence d'efficacité serait perceptible de quelque manière que ce soit dans une application réelle. Vous devez donc prendre votre décision en fonction de la qualité du code (lisibilité et sécurité), ce qui devrait vous conduire à utiliser un enum 99% du temps .

3voto

Óscar López Points 97105

N'oubliez pas que enums sont sûrs en termes de type, et vous ne pouvez pas mélanger les valeurs d'un enum avec un autre. C'est une bonne raison de préférer enums sur ints pour les drapeaux.

D'autre part, si vous utilisez ints pour vos constantes, vous pouvez mélanger les valeurs de constantes non liées, comme ceci :

public static final int SUNDAY = 1;
public static final int JANUARY = 1;

...

// even though this works, it's a mistake:
int firstMonth = SUNDAY;

L'utilisation de la mémoire de enums sur ints est négligeable, et la sécurité de type enums rend les frais généraux minimaux acceptables.

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