Newsgroup: it.comp.java
Titolo: effetto clone senza clonable ?

qualcuno puň spiegarmi questa ?
ho messo in un vector un mio oggetto tipo formato da un campo int, 2
String ed una classe Integer
public class Fprofili {
    public int ID;
    public String profilo;
    public String descrizione;   
    public String note;
    public Integer prova;
Ho valorizzato il Vector con una nuova istanza dell'origine dati: 
Vector bufferProfili = new Vector();
Fprofili rigaelenco = new Fprofili(); //<= origine dati da intabellare
                Fprofili riga = new  Fprofili();    //< nuova istanza
                riga.ID = rigaelenco.ID;
                riga.profilo = rigaelenco.profilo;
                riga.descrizione = rigaelenco.descrizione;
                bufferProfili.addElement( riga);
Ebbene cosě facendo riprendendo il Vector con:
                riga = (Fprofili) bufferProfili.get(i);
mi trovo nel vettore gli oggetti di tipo Fprofili correttamente cosě
come li ho aggiunti, mentre mi aspettavo che almeno il campo Integer
venisse spostato per riferimento
infatti nella prova che feci prima, mettevo nel vector direttamente
rigaelenco e non una nuova istanza del suo tipo, e quindi quando
rileggevo il vector avevo in canna sempre l'ultimo elemento aggiunto e
non una copia di tuggli elementi dell'origine dati venendo quindi
bugerato.
idem (vengo bugerato con l'effetto ultimo) anche se metto nel vector
una nuova istanza del tipo Fprofili ma valorizzandola direttamente
dalla classe dall'origine dati e non impostando ogni suo elemento;
ovvero facendo:
                Fprofili riga = new  Fprofili();    //< nuova istanza
                riga = rigaelenco;
                bufferProfili.addElement( riga);
Capisco che come dall'esempio in testa, riga e rigaelenco non hanno
nulla in comune, ma l'oggetto Integer prova che sposto da una istanza
all'altra č lo stesso, no? o fa eccezzione anche lui come le stringhe?
Ora a me sta bene cosi (mi č piů comodo intabellare nel vector un
oggetto per tipo invece di una array di object)
ma non capisco perchč funziona.



 ma non capisco perchè funziona.
	Non riesco a capire la tua domanda, anche perché non vedo mai quando 
assegni l'oggetto Integer prova... Se mi fai vedere bene il codice forse 
posso spiegarti.
	Ricorda una cosa però, anche se java non usa "puntatori" tutte le 
variabili che rappresentano istanze ad un oggetto sono di fatto 
"puntatori" alla memoria dove si trova l'istanza stessa!
	A presto
	Gian Luca

 qualcuno pu• spiegarmi questa ?
Alla cieca, nove su dieci stai riassegnando ogni volta lo stesso 
riferimento mentre pensi di stare assegnandone uno nuovo.

 
Hai ragione Gian Luca, nell'esempio mancava la 
           riga.prova = rigaelenco.prova;
prima della   bufferProfili.addElement(riga);
Comuque ho fatto un piccolo codice che allego im modo che sia piů
esaustivo.
mi ripeto; capisco l'errore nel caricamento con il ciclo "carica"
ma non mi spiego perchč funzioni il caricamento con il ciclo "caricaX"
Per la precisione, il campoC č una classe Integer, che nel caricaX
referenzio con
            comodo.campoC = trac.campoC;
prima di fare  vv.addElement(comodo);
Mi aspettavo quindi che campoA e B siano stati portati nel vector per
valore,
mentre il campoC per riferimento, anche se questo riferimento č
contenuto
in un nuovo oggetto (comodo).
Ed invece si ottiene una copia esatta di tutto l'oggtto tracciato.
grazie
/*
 * prov.java
 *
 * Created on 11 agosto 2004, 16.17
 */
package Prove;
import java.util.*;
/**
 *
 * @author  Luciano996
 */
public class prov {
    int conta=0;
    Vector vv =new Vector();
    Tracciato trac;
 
    /* impilo in vector */
    public void carica() {
        System.out.println("CASO CON CARICAMENTO FASULLO (a
ragione)");
        trac =  new Tracciato();
        for (int i=0;i<5;i++) {
            trac.calcolo();
            vv.addElement(trac);
        }
    }
    /* impilo in vector */
    public void caricaX() {
        System.out.println("\nCASO CON CARICAMENTO NON COMPRESO");
        trac =  new Tracciato();
        for (int i=0;i<5;i++) {
            trac.calcolo();
            Tracciato comodo = new Tracciato();
            comodo.campoA = trac.campoA;
            comodo.campoB = trac.campoB;
            comodo.campoC = trac.campoC;
            vv.addElement(comodo);
        }
    }    
    /* scarico il vector e stampo contenuti */
    public void scarica() {
        for (int i=0;i<vv.size();i++) {
            trac =  (Tracciato) vv.get(i);
            System.out.println("Estrazione"+i+"=
campoA:"+trac.campoA+" campoB:"+trac.campoB+" campoC:"+trac.campoC);
        }
    }    
 
//    public Tracciato richiama() {
//    }    
 
    public  class Tracciato {
 
        int campoA;
        String campoB;
        Integer campoC;
 
        public void calcolo() {
            conta++;
            campoA=conta; 
            campoB=Integer.toString(conta);
            campoC=new Integer(conta);
            System.out.println("Oggetto campoA:"+campoA+"
campoB:"+campoB+" campoC:"+campoC);
        }
    }
    public static void main(String[] args) {      
        prov aa = new prov();
        aa.carica();
        aa.scarica();
 
        aa = new prov();
        aa.caricaX();
        aa.scarica();
    }
 
}
}
SYSOUT
CASO CON CARICAMENTO FASULLO (a ragione)
Oggetto campoA:1 campoB:1 campoC:1
Oggetto campoA:2 campoB:2 campoC:2
Oggetto campoA:3 campoB:3 campoC:3
Oggetto campoA:4 campoB:4 campoC:4
Oggetto campoA:5 campoB:5 campoC:5
Estrazione0= campoA:5 campoB:5 campoC:5
Estrazione1= campoA:5 campoB:5 campoC:5
Estrazione2= campoA:5 campoB:5 campoC:5
Estrazione3= campoA:5 campoB:5 campoC:5
Estrazione4= campoA:5 campoB:5 campoC:5
CASO CON CARICAMENTO NON COMPRESO
Oggetto campoA:1 campoB:1 campoC:1
Oggetto campoA:2 campoB:2 campoC:2
Oggetto campoA:3 campoB:3 campoC:3
Oggetto campoA:4 campoB:4 campoC:4
Oggetto campoA:5 campoB:5 campoC:5
Estrazione0= campoA:1 campoB:1 campoC:1
Estrazione1= campoA:2 campoB:2 campoC:2
Estrazione2= campoA:3 campoB:3 campoC:3
Estrazione3= campoA:4 campoB:4 campoC:4
Estrazione4= campoA:5 campoB:5 campoC:5

         }
L'errore che tu fai, caro Luciano (se di errore vogliamo parlare), è 
nella parte che ho evidenziato. Il metodo calcola genera un'istanza di 
un oggetto Integer ogni volta che il metodo viene invocato. Significa 
che se vieni invocato 5 volte, vengono creati 5 oggetti in memoria 
contenenti i valori e ad ogni iterazione perdi il riferimento 
all'oggetto precedente (e quindi non essendo più consultabile il garbage 
collector lo elimina). Di fatto, nel primo esempio (carica), quattro dei 
5 oggetti che crei vengono perduti e solo l'ultimo viene tenuto. (è 
l'effetto che ottieni perché utilizzi sempre lo stesso puntatore trac 
per tenere la struttura che a sua volta utilizza sempre lo stesso 
puntatore per riferire un singolo oggetto).
Quando invece utilizzi "comodo" in appoggio, in realtà ottieni 5 oggetti 
tracciato diversi (perché fai il new) che al loro interno hanno 5 
puntatori al campo Integer diversi che possono quindi riferirsi ai 5 
oggetti in memoria di tipo Integer, che non vengono persi.
Non so se sono stato chiaro, ma il "trucco" non è nel puntatore di 
"Integer", ma di quello di trac 5 oggetti trac -> 5 puntatori Integer, 1 
oggetto trac -> 1 puntatore Integer disponibile (che punta solo 
all'ultimo istanziato)...
Mannaggia, ci vorrebbe un po' di carta e un piccolo disegnino per farti 
vedere :(
A presto
Gian Luca

 Gian Luca
Grazie Gian Luca, č vero sono sempore oggetti diversi