Newsgroup: it.comp.java
Titolo: secondo voi....

...č pensata bene la traduzione in Java di questo tipo di dato in C++?
typedef enum
	{
	ATTRIBUTE_TYPE__INTEGER,
	ATTRIBUTE_TYPE__DATE,
	ATTRIBUTE_TYPE__STRING
	}
	AttributeType;
tradotto in Java cosě:
//**********************************************
public class AttributeType{
	private String attributeType;
 
	AttributeType(String aT){
		setAttributeType(aT);
	}
 
	private void setAttributeType(String aT){
		if (checkAttributeType(aT))
			attributeType=aT;
		/*else
			fa qualcosa...
		*/			
	}
 
	private boolean checkAttributeType(String aT){
		if (aT.equals("INTEGER") || aT.equals("STRING") || aT.equals
("DATE"))
			return true;
		return false;
	}
 
	public String returnAttributeType(){
		return attributeType;
	}
 
	//esempio di utilizzo..
	public static void main(String args[]){
		AttributeType attributeType=new AttributeType("STRING");
		System.out.println("Il tipo dell'attributo e': 
"+attributeType.returnAttributeType());
	}
}
grazie per l'attenzione e ciao a tutti...
Luca

      AttributeType;
Piu' compatto, e piu' aderente alla semantica originale:
public interface AttributeType {
    	public static final int INTEGER = 0;
    	public static final int DATE = 1;
     	public static final int STRING = 2;
}
ovunque il codice C++ usa ATTRIBUTE_TYPE__<x>, usi AttributeType.<x>
Farne il porting in termini di oggetti, come proponevi, puo' o meno
essere il caso a seconda di com'e' il codice esistente e del rapporto
costo/benefici. 
-- 
Life's something u don't get out alive..
ObjectZone - 
http://space.tin.it/computer/csadun

 }
Se poi si vuole qualcosa di piu' "type-safe", si puo' fare:
public class AttributeType {
   private AttributeType(String name) [
     this,name = name;
   }
   public String toString() {
     return name;
   }
   public static final AttributeType INT = new AttributeType("int");
   public static final AttributeType DATE = new AttributeType("date");
   public static final AttributeType STRING = new AttributeType("string");
   private String name;
}
ciao
uL

 public interface AttributeType {
Ripensandoci, meglio dichiarare "public final class AttributeType" invece di 
interface.


siete stati molto precisi e vi ringrazio per l'aiuto.
grazie anche a M.Mercogliano... 
ciao
Luca

 >
che ne pensate invece di questa traduzione?
static final String[] AttributeType={
	"INTEGER",
	"DATE",
	"STRING"
}
forse però si perde il controllo di tipo durante la compilazione.
dico bene?...
ciao
Luca

 dico bene?...
Piu' che altro, richiede piu' sforzo per convertire il codice: in C++
avrai usi delle costanti come: 
 switch(type) {
    	case ATTRIBUTE_TYPE__STRING:
    	    	...
    	..eccetera..
 }
 o if (type==ATTRIBUTE_TYPE__STRING) { ... } che richiedono riscrittura o
 adattamento con "equals" se usi oggetti - dato che Java non ha operator
 oveloading. 
Mantenendo costanti intere invece si portano senza problemi. Del resto,
se il design originale le usa, spesso lo fa a ragion veduta. 
Altre volte invece vuoi fare un po' di reenginering e "oggettificare" -
ma su cose come queste spesso non vale la pena - gli overhead e lo sforzo
di adattamento del codice sono grandi, e il codice originale in genere e'
gia' testato. Chiaro che in casi particolari puo' valere - e'
semplicemente una linea guida. 


   public static final AttributeType INT = new AttributeType("int");
[CUT]
e se vogliamo aderire alla semantica originaria senza perdere in
"type-safe" ( e soprattutto se il progetto permette un dispendio
leggermente maggiore in termini di linee di codice da digitare ... ;-)
), possiamo utilizzare una soluzione intermedia:
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
class AttrSet {
  private static int currID = 0;
  private synchronized static final int getNextID() { 
    return currID++;
  }
  // ========================
  // ENUMERATION SET
  // ========================
  public static final AttrSet INT    = new AttrSet();   // ==> 0
  public static final AttrSet DOUBLE = new AttrSet(20); // ==> 20
  public static final AttrSet FLOAT  = new AttrSet();   // ==> 21
  private final int ID;
  private AttrSet() {
    this.ID = getNextID();
  }
  private AttrSet( int iID ) {
    currID  = iID;
    this.ID = getNextID();
  }
  public int hashCode() { return ID; }
  public String toString() {
    return String.valueOf( ID );
  }
  public boolean equals( Object ob ) {
    return  ob instanceof AttrSet && ((AttrSet)ob).ID == ID;
  }
  public static AttrSet valueOf( String name ) {
    try {
      Field fields[] = AttrSet.class.getDeclaredFields();
      for (int iField=fields.length-1; iField >= 0; iField-- ) {
        Field currField = fields[iField];
        if (    AttrSet.class.isAssignableFrom( currField.getType() )
             && Modifier.isStatic( currField.getModifiers() ) ) {
          if ( currField.getName().equalsIgnoreCase( name ) ) {
            return (AttrSet) currField.get(null);
          }
       }
     }
    } catch( Exception ex ) {
      // How can I reach this line ????
      throw new UnknownError( "Unknown error: " + ex.toString() );
    }
    throw new IllegalArgumentException("..."); 
  }
}
public class TestEnumeration {
  public static void main( String argv[] ) {
    System.out.println( AttrSet.DOUBLE );
    System.out.println( AttrSet.valueOf("float") );
  }
}
La classe ora è il più simile possibile ad un enumerato C++ ed è
type-safe.
Il metodo valueOf è stato inserito perchè, sulla base del quesito
originario, mi è parso di capire che lo sviluppatore potrebbe avere la
necessità di caricare i dati da un file di configurazione (magari XML)
e ricavare l'analoga struttura dati in forma rapida e semplice.
----
E' ovviamente possibile generalizzare alcuni metodi e raccoglierli in
una classe base magari chiamata "AbstractEnumeration", ma comunque è
bene ricordare che ogni caso può presentare peculiarità diverse;
si guardi ad es. un enumerato utile a modellare un comportamento:
abstract class PaintTool {
  public static final BRUSH_TOOL = new PaintTool() {
    public void paint(Graphics g) { .. }
  }
  public static final PEN_TOOL = new PaintTool() {
    public void paint(Graphics g) { .. }
  }
 .....
  public abstract void paint(Graphics g);
  public boolean equals( Object ob ) {
    return 
        ob != null 
     && ob.getClass().getName().equals( getClass().getName() );
  }  
}
In tal caso equals è stato modificato per non incorrere in problemi
legati a multiple istanze da parte di diversi classloader utente (in
questo caso infatti il nome univoco della classe anonima rappresenta
l'unica informazione necessaria per identificare la nostra particolare
istanza).
Ciao, Max.

		return attributeType;
[CUT]
Il vantaggio di usare classi per tipizzare oggetti risiede spesso
anche nell' "evitare di riccorrere a catene di if/then/else e/o
switch" per risolvere tipi, soprattutto per quelle operazioni che
vengono svolte con maggiore frequenza (come il setAttributeType in
questo caso); una soluzione come quella da te proposta offre una
garanzia di "check centralizzato", per cui puoi facilmente cambiare
quantità e valore dei parametri ammessi senza creare errori di
compilazione nel resto del codice (ovviamente l'errore nasce a
run-time se si rimuove unattributo usato ;-) ), però a mio avviso ha
più svantaggi che vantaggi, evidenti soprattutto se il numero di
parametri enumerati è elevato (diventa difficile gestire persino il
controllo sul codice).
Dalla mia esperienza posso dirti che gli enumerati spesso nascono
quasi per caso come raccoglitori di variabili che si è verificato
essere usate da più blocchi di codice in classi diverse; 
in prima istanza dunque si hanno classi del tipo
  class UserRole { 
    public static final int SYSTEM_ADMINISTRATOR = 1;
    public static final int BACKUP_ADMINISTRATOR = 2;
    public static final int USER_ADVANCED = 3;
    public static final int UNDEFINED = 4;
  }
in un secondo tempo, se l'utilizzo diventa più frequente, si ha un
raffinamento delle classi per giungere a versioni sempre più
elaborate, magari giungendo a classi che racchiudono a loro volta più
sottotipi ognuno con i suoi enumerati... ;  ma in tal caso l'interesse
rivolto alla "cura del dettaglio" è più che giustificato dall'utilizzo
massiccio che ne viene fatto. Come vedi, non esiste una soluzione
unica al tuo problema, e dipende molto dal tempo a tua disposizione (
tenendo conto che l'obiettivo primario di un progetto è il rispetto
delle specifiche date entro le scadenze prestabilite, non il design
alla base ).
Ciao, Max.