Visualizzazione dei risultati da 1 a 7 su 7

Discussione: Dubbi su Reflection

  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    36

    Dubbi su Reflection

    Ho studiato da poco la reflection in java ed ho dei dubbi su come utilizzarla.
    Vi faccio un esmepio:
    Ho creato delle classi A, B, C. Tutte e tre estendono una certa classe X e ognuna ha due campi, uno stringa e un intero. Devo creare queste classi leggendo le informazioni da un file di testo. Il file è strutturato in questo modo:
    NomeClasse Stringa Intero
    Io non so a priori se tutte e tre le classi saranno create, ne se c'è un ordine specifico in cui le informazioni sono salvate nel file. Per creare quindi una o più di queste classi è corretto scrivere questo frammento di codice?


    codice:
    Class<?> c=Class.forName("X");
    Class<? extends X> classe=c.asSubClass(X.class);
    String[] nomiClassi, stringhe, interi;
    ......
    ........
    leggo dal file i dati
    .....
    .....
    Constructor<? extends X> costr=classe.getConstructor(String.class, Integer.class);
    X temp=costr.newinstance(stringa, intero);
    
    while(i<nomiClassi.lenght) {
    if(nomiClassi[i].compareTo("A")==0)
        A classeA=(A) temp;
    else
          if(nomiClassi[i].compareTo("B")==0)
                   B classeB=(B) temp;
          else
               if(nomiClassi[i].compareTo("C")==0)
                     C classeC=(C) temp;
    
    i++;
    }
    Se fosse corretto allora non capisco perchè usare la reflection se la stessa cosa si potrebbe fare in quest'altro modo:
    codice:
    String[] nomiClassi, stringhe, interi;
    ......
    ........
    leggo dal file i dati
    .....
    .....
    int i=0;
    while(i<nomiClassi.lenght) {
       if(nomiClassi[i].compareTo("A")==0)
          A classeA=new A(stringhe[i], interi[i]);
       else
          if(nomiClassi[i].compareTo("B")==0)
                   B classeB=new B(stringhe[i], interi[i]);
          else
               if(nomiClassi[i].compareTo("C")==0)
                     C classeC=new C(stringhe[i], interi[i]);
    
    i++;
    }

  2. #2
    Usata in questo modo non è che abbia tanto senso in effetti.
    Ma nel file di testo non é per caso che ti viene specificato il full class name, perché in questo caso allora si che avrebbe senso usare la reflection

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    36
    No solamente il nome della classe in formato stringa. Copio uno spezzone del file di testo:

    APERTURE:
    APERT_1 Porta Porta del porto LOC_1 LOC_2
    APERT_2 Finestra Passaggio LOC_3 LOC_4
    APERT_6 Porta Porta della House of Mojo LOC_1 LOC_5
    APERT_3 Botola Un passaggio segreto multidimensionale LOC_5 LOC_6 # chiusa per default, aperta da un bottone o una leva, Dalla House of Mojo al palazzo del governatore (!)
    APERT_4 PassaggioSegreto Un passaggio segreto per la fine LOC_6 LOC_7 # Porta alla fine del gioco
    APERT_5 Porta Porta del retro LOC_2 LOC_4 # porta chiusa di default

    - APERT_1/APERT_2/ecc sarebbe un campo String che indica l'ID della classe
    - Porta/Finestra/Botola/cc è il nome stesso della classe che estende la superclasse Aperture
    - Porta del porto/Passaggio/ecc spiega che tipo di porta/botola/ecc è
    - LOC_1/LOC_2/ecc sono altri ID che si riferiscono a locazioni.

    Il file in sostanza è strutturato in questo modo, conviene usare la reflection oppure no? Perchè comunque reflection o no devo fare degli if nidificati per ogni specifico caso per creare le classi concrete

  4. #4
    Se le classi sono tutte dentro un package specifico allora puoi evitare gli if caricando ed instanziando direttamente la classe letto.
    Faccio un esempio in pseudo codice
    codice:
    //leggo il nome della classe
    String nomeClasse = ....
    //package di default
    String packageName=it.test
    Class<? extend X> clazz = Class.forName(packageName+nomeClasse)
    //ottengo il costruttore
    ......
    //creo instanza
    constructor.newInstance(....) // questo ti restituirà un instanza assegnabile alla classe X.
    Ovviamente questo ha un senso se puoi lavorare direttamente sul super tipo X altrimenti è molto meglio fare gli if annidati per ottenere direttamente la sottoclasse.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    36
    Ok grazie mille! Le classi hanno una superclasse ma è astratta quindi ho risolto con le if in cascata
    ho un ulteriore problema però, è abbastanza stupido ma non riesco a venirne a capo.
    Leggo dal file due stringhe: un ID e un nome della classe. Con queste stringhe devo creare delle Locazioni. Questo è il codice ad esempio:
    String ID=letto dal file..
    String nome=letto da file...

    Location locazione=new Location(ID, nome);

    Questa classe poi la inserisco in ArrayList<Location>. Il porblema è che la classe avrà sempre lo stesso nome "locazione", quindi quando la aggiungo nell'ArrayList la stringa ID di una precedente locazione aggiunta mi viene sostituita. Esempio:

    1) ArrayList: {null}
    2) ArrayList: {new Location("LOC_1", "Porto")}
    Quando poi aggiungo una seconda locazione succede questo
    3) ArrayList: {new Location("LOC_2", "Porto") , new Location("LOC_2", "Casa")}

    La stringa ID della prima locazione aggiunta viene automaticamente sostituita dall'ID della seconda locazione. Perchè?

  6. #6
    Il problema sicuramente non è collegato all'Arraylist, sicuramente farai qualcosa che modifica il valore di quell'oggetto prima o dopo l'inserimento nella lista.
    Posta il codice e vediamo di venirci a capo.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    36
    Questo è il codice, l'ArrayList si chiama locations:

    codice:
    private String loadLocations(Scanner in, String ID, String name){
    		do {
    			if(ID.compareTo("APERTURE")!=0) {
    				name=in.nextLine();
    				
    				if(name.contains("#"))
    					name=stringContainsMessage(name);
    				
    				String[] tempName=name.split("\\t");			
    				for(int j=0;j<tempName.length;j++)				
    					if(!tempName[j].isEmpty())
    						name=tempName[j];
    
    				//createLocation() costruisce la locazione
    				Location location=createLocation(ID, name);
    				System.out.println(location.getID() + location.getName());
    				
    				CurrentLocation2D currentLocation=null;
    				
    				if(location.getID().compareTo("LOC_1")==0){
    					currentLocation=new CurrentLocation2D(location, mainFrame);
    					locations.add(currentLocation);
    				}
    				else	
    					locations.add(location);
    				
    				System.out.println("ARRAYLIST");
    				for(int i=0;i<locations.size();i++){
    					Location temp=null;
    					if(locations.get(i) instanceof CurrentLocation2D){
    						CurrentLocation2D tempCurrentLocation (CurrentLocation2D) locations.get(i);
    						temp=tempCurrentLocation.getCurrentLocation();
    					}else
    						temp=locations.get(i);
    						
    					System.out.println(temp.getID() + temp.getName());
    				}
    
    				
    			}
    
    			ID=in.next();
    		
    		}while(ID.compareTo("APERTURE")!=0);
    		
    		if(!in.hasNext())
    			ID=null;
    		
    		return ID;
    		
    	}
    Ho messo anche dei System.out.println per verificare le varibili e finchè viene creata la locazione con createLocation() l'ID e il nome sono corretti, poi aggiungo l'istanza all'ArrayList e quando lo stampo, già dalla seconda locazione aggiunta succede il pasticcio

    EDIT:
    Ho trovato l'errore! E' nel campo ID della classe Location che per sbaglio l'ho messo static e quindi ogni volta veniva modificato

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.