1

'lut,
j'ai un problème avec les enum en java :

comme je dois donner des valeurs particulières dans mon enum, j'ai ajouté un attribut id qui stocke cette valeur

public class Chunk3DS
{
  //[...]
  public enum ChunkType
  {
    MAIN_CHUNK(0x4d4d),
   //[...]
    3DS_VERSION(0x0002) ;
    
    private int id ;
    private ChunkType( int id ) { this.id= id ; }
    public int getID() { return id ; }
  }
}




Ensuite, dans mon programme je lis dans un fichier des entiers 16bits qui correspondent aux valeurs stockées dans l'attribut ID de mon enum.

La question est la suivante : comment faire pour transformer l'entier 16 bits lu dans le fichier en un enum Chun3DS.ChunkType ??? (sans se tapper toute l'enumeration avec un foreach pour comparer les valeurs (à priori je suppose que je pourrais mettre ça dans une méthode static de mon enum ChunkTypes mais je trouve ça idiot de faire un foreach pour trouver une valeur et de faire un switch sur l'enum trouvé juste derrière))

en gros ce que je voudrais pouvoir faire c'est :
Chunk3DS.ChunType monEnum= readAShortFromFile(file) ;
switch ( monEnum ) {
  case MAIN_CHUNK: action1() ; break ;
  case 3DS_VERSION: action2() ; break ;
 //...
}


edit : correction de quelques erreurs

2

heu, merci d'avance au fait hehe

3

Euh...
Je trouve ça un peu confus en fait, malgré tes explications.
Ton énum s'appelle ChunkType ou ChunkTypes ?
Ton id est il un attribut de ta classe Chunk3DS ou de ton énumération ChunkTypes ?
De même, je suppose que le constructeur "private ChunkTypes( int id ) { this.id= id ; }" est le constructeur de ton énumération !?

public class Chunk3DS  { 

  public enum ChunkTypes { 
     MAIN_CHUNK(0x4d4d),
     3DS_VERSION(0x0002) ; 
  
      private ChunkTypes( int id ) { this.id= id ; } 
      private int id ; 
      public getId() { return id ; } 
   }
} 
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.

4

oups, j'ai tapé trop vite, un instant.. triso
smeet :
Euh...
Je trouve ça un peu confus en fait, malgré tes explications.
Ton énum s'appelle ChunkType ou ChunkTypes ?
Ton id est il un attribut de ta classe Chunk3DS ou de ton énumération ChunkTypes ?
De même, je suppose que le constructeur "private ChunkTypes( int id ) { this.id= id ; }" est le constructeur de ton énumération !?

[li]Disons que l'enum s'appelle ChunkTypes
[li]id est attribut de l'enum ChunkTypes en effet
[li]private ChunkTypes( int id ) est bien le constructeur


public class Chunk3DS  { 

  public enum ChunkTypes { 
     MAIN_CHUNK(0x4d4d),
     3DS_VERSION(0x0002) ; 
  
      private ChunkTypes( int id ) { this.id= id ; } 
      private int id ; 
      public int getId() { return id ; }  // j'avais oublié le type de retour aussi #gol#
   }
} 

oui, quand c'est bien écrit ça ressemble à ça oui

5

Voilà ce que j'en pense.
Si j'ai bien saisi le fonctionnement des enums (je ne suis pas un grand pro), ton code va générer un class, équivalent au code suivant :

public static class ChunkTypes implements Serializable, Comparable {
   public static final ChunkTypes MAIN_CHUNK;
   public static final ChunkTypes 3DS_VERSION;

   private int id;
   private ChunkTypes(int id) {
      this.id= id ; 
   }  
   public int getId() {
      return id ;
   }  

   public static ChunkTypes valueOf(String s) {
      //code obscur du genre :
      if ("MAIN_CHUNK".equals(s)) {
         return ChunkTypes.MAIN_CHUNK;
      } else if () {
         return ChunkTypes.3DS_VERSION;
      }
      throw nex IllegalArgumentException(...);
      //...
      //c'est cette méthode qui sera appelé lorsque tu feras Enum.valueOf(ChunkTypes.class, s), la jvm délèguera au ChunkTypes par introspection.

   }

 //... autres méthodes telles que equals, hashcode, tostring, 
}
(le tout en inner class de Chunk3DS, pour le coup)

A partir de là, si mes suppositions sont justes (!), tu dois pouvoir écrire :

Chunk3DS.ChunkTypes monChunkType = new Chunk3DS.ChunkTypes(monEnum);

Hélas, je n'ai pas la possibilité de vérifier ici si ca marche .
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.

6

heu, mais le constructeur est obligatoirement privé, non ? (D'après ce que j'ai compris il est juste appelé en interne)

sinon j'ai trouvé ça qui est intéressant mais ne répond pas à la question : http://mindprod.com/jgloss/enum.html (passe mal sous firefox, sous IE c'est bon)

7

bon je rentre et je teste, on verra bien
merci en tous cas

8

Bon,
Je viens de vérifier: effectivement, le constructeur d'une énum est toujours priate, et on ne peut pas instancier de nouveaux éléments dans l'énum (bon, c'est normal après tout).

Je vais continuer d'y réfléchir.
En attendant, note aussi que tu n'as pas le droit d'appeler un élément "3DS_VERSION": un identificateur ne peut pas commencer par un chiffre tongue)
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.

9

smeet :
Bon,
Je viens de vérifier: effectivement, le constructeur d'une énum est toujours priate, et on ne peut pas instancier de nouveaux éléments dans l'énum (bon, c'est normal après tout).

c'est bien ce qu'il me semblait avoir lu sad

Je vais continuer d'y réfléchir.

sinon je vois une solution, mais je trouve que c'est un peu abuser que d'être obligé de faire ce genre de choses :
faire une table de correspondance statique avec en entrée les valeurs des ID, et en sortie les ordinaux des identificateurs correspondants (64ko mais tant pis..)

static Chunk3DS.ChunkTypes int2enum(int entierLuDansFichier)
{
  return values()[tableCorrespondance[entierLuDansFichier]];
}




En attendant, note aussi que tu n'as pas le droit d'appeler un élément "3DS_VERSION": un identificateur ne peut pas commencer par un chiffre tongue)

Arf, oui, c'est vrai cheeky Mais bon ça n'est pas le plus grave #huhu#

10

sinon je vois une solution, mais je trouve que c'est un peu abuser que d'être obligé de faire ce genre de choses : faire une table de correspondance statique avec en entrée les valeurs des ID, et en sortie les ordinaux des identificateurs correspondants (64ko mais tant pis..)


Oui, j'y pensais.
Puisque tu définis déjà es vleurs en dur dans ton énumération, pourquoi ne pas écrire une petite factory dans cette même enum tant qu'à y etre...
Bon, j'aimerais bien avoir la "solution" de quelqu'un qui connait bien ce sujet.
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.

11

Pen^2
: faire une table de correspondance statique avec en entrée les valeurs des ID, et en sortie les ordinaux des identificateurs correspondants (64ko mais tant pis..)

Oui, on dirait que c'est ce qu'il y a de plus simple. Et d'ailleurs Java fait tout le boulot avec la méthode statique values() qui retourne le tableau avec pour index l'ordre de déclaration des constantes (mais dans ce cas il faut que tous les nombres soient couverts). Si c'est pas le cas, on doit pouvoir se débrouiller en implémentant equals() et en créant une Collection à partir du tableau.
Pour les 64ko, dans tous les cas il interviendront quelque part, et de toute façon il seront consommés qu'à l'instanciation du tableau.

12

finalement avec l'histoire du tableau ça fonctionne, mais j'ai fait une seconde version avec une HashMap (c'est quand même beaucoup mieux et portable (pas limité à 16 bits, pas de trous, renvoit direct de null si la clé n'existe pas, etc...)
4d4d)) ; // #huhu#      } }pour ceux que ça intéresse : public class Chunk3DS {      public static enum Chunk3DSType      {         MAIN3DS_4D4D                                    ( 0x4d4d ),         FILE_VERSION_0002                               ( 0x0002 ),           // [...]         PERCENT_INT_0030                                ( 0x0030 ),         PERCENT_FLOAT_0031                              ( 0x0031 ) ;         private int id ;         private Chunk3DSType( int id )         {            this.id=id ;         }         /* // V1 (avec un tableau)         private static final int[] int2EnumOrdinal= new int[65536] ;         static {            for ( int i= 0 ; i < int2EnumOrdinal.length ; i++ )               int2EnumOrdinal[i]= -1 ;            for ( Chunk3DSType chunkId : Chunk3DSType.values() )               int2EnumOrdinal[chunkId.id]= chunkId.ordinal() ;         }         public static Chunk3DSType int2Chunk3DSType( int n )            throws IndexOutOfBoundsException         {            int enumOrdinal= int2EnumOrdinal[n] ;            if ( enumOrdinal < 0 )               throw new IndexOutOfBoundsException() ;            else               return values()[enumOrdinal] ;         }         */         // V2 (avec un HashMap)         private static HashMap<Integer, Chunk3DSType> int2Enum            = new HashMap<Integer, Chunk3DSType>(Chunk3DSType.values().length) ;         static {            for ( Chunk3DSType chunkId : Chunk3DSType.values() )               int2Enum.put(chunkId.id, chunkId) ;         }         public static Chunk3DSType int2Enum( int n )         {            return int2Enum.get(n) ;         }      } } public class TxtMain {      public static void main( String[] args )      {           System.out.println(Chunk3DS.Chunk3DSType.int2Enum(0x

merci à tous smile (edit : enfin à vous deux hehe)

13

smeet
:
sinon je vois une solution, mais je trouve que c'est un peu abuser que d'être obligé de faire ce genre de choses : faire une table de correspondance statique avec en entrée les valeurs des ID, et en sortie les ordinaux des identificateurs correspondants (64ko mais tant pis..)


Oui, j'y pensais.

les grands esprits se rencontrent alors hehe

Puisque tu définis déjà es vleurs en dur dans ton énumération, pourquoi ne pas écrire une petite factory dans cette même enum tant qu'à y etre...

mm, oui, peut etre, je ne sais pas, je n'ai pas trop reflechi (là à froid je ne vois pas exactement comment)

Bon, j'aimerais bien avoir la "solution" de quelqu'un qui connait bien ce sujet.

Tout ce que je peux te dire, c'est qu'à la fin de la doc du J2SE qui présente les enums, ils parlent d'une nouvelle classe EnumMap qui permet d'associer une valeur pour chaque clé de l'enum.)
Ca n'a donc pas l'air de les choquer d'utiliser une structure statique suplémentaire dans l'enum pour stocker des infos.
Comme en ce qui me concerne la clé de ma Map est un entier et pas un enum, j'ai utilisé une HashMap *normale*.

14

Très bonne idée, la HashMap. Avec l'autoboxing du java 5, ca rend l'écriture dans ton code encore plus légère.
Quand je parlais de "factory" c'est ce genre de méthode ce à quoi je pensais.

Après, au nveau conception de code, il faut voir s'il est mieux de retourner null quand il n'existe pas de ChunkType, ou s'il est mieux de thrower une exception (là, çé depend surtout de ta vision des choses).
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.

15

oui, c'est drolement bien l'autoboxing smile. Ils ont vraiment ajouté des nouvelles fonctionnalités interessantes love

factory > ok, parfait smile

null ou exception > moui, à prioiri pour le cas présent j'aime autant renvoyer null (je changerais peut etre remarque, on verra)