Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    Domanda su writeObject/readObject

    Ciao a tutti!!!
    Avrei una domanda da fare. Passo prima un oggetto come parametro a writeObject e poi lo leggo con readObject. E' possibile che uno di questi due metodi mi modifica il riferimento all'oggetto?
    Perchè ho notato questa cosa in una applicazione che sto facendo e a me servirebbe che il riferimento resti invariato.
    Potete dirmi se è proprio così? Grazie.

  2. #2

    Re: Domanda su writeObject/readObject

    Originariamente inviato da francordine
    Avrei una domanda da fare. Passo prima un oggetto come parametro a writeObject e poi lo leggo con readObject. E' possibile che uno di questi due metodi mi modifica il riferimento all'oggetto?
    La risposta ovviamente è no.

    In quale contesto stai utilizzando i flussi? Per scrivere e leggere in file/socket/altro?

  3. #3
    E' una applicazione client server che utilizza stub e skeleton.

    Praticamente ho un oggetto A che ha tra i suoi campi un array di oggetti B;
    la classe B implementa Serializable;

    L'oggetto A ha un metodo che mi restituisce un riferimento ad un oggetto B prelevandolo da questo array.

    Ora, quando uso questo metodo nello skeleton il riferimento a questo oggetto B che ottengo da esso lo devo scrivere nel socket con writeObject, il riferimento a B che leggo dallo stub con readObject (facendo anche il cast a B) è diverso da quello che ho scritto nello skeleton. E' come se mi copia i campi dell'oggetto B e ne costruisce uno nuovo.

  4. #4
    Originariamente inviato da francordine
    E' una applicazione client server che utilizza stub e skeleton.
    Ok, magari posta la parte di codice che interessa il problema..

  5. #5
    Questo è il metodo presente nella classe che implementa l'interfaccia
    codice:
    public synchronized Risorsa richiedi(int idUtente) throws GiaAssegnata, InterruptedException
    	{
    		if (posRisorsaUtente(idUtente) != -1)
    			throw new GiaAssegnata();
    		while (risorseLibere == 0)
    			this.wait();
    		Risorsa tmp = null;
    		for (int i = 0; i < maxRisorse; i++)
    			if (libera[i])
    			{
    				richiesta = memo[i];
    				tmp = memo[i]; //copio il riferimento dell'oggetto Risorsa in tmp
    				utenti[i] = idUtente;
    				libera[i] = false;
    				risorseLibere--;
    				break;
    			}
    		this.notifyAll();
    		return tmp;
    	}
    Questo è quello che implementa lo stub
    codice:
    public Risorsa richiedi(int idUtente) throws GiaAssegnata, InterruptedException, IOException
    	{
    		Object tmp = null;
    		out.writeObject("ric");
    		out.writeObject(new Integer(idUtente));
    		try
    		{
    			tmp = in.readObject();
    		}
    		catch (ClassNotFoundException e)
    		{
    			throw new IOException();
    		}
    		if (tmp instanceof GiaAssegnata)
    			throw (GiaAssegnata)tmp;
    		else if (tmp instanceof InterruptedException)
    			throw (InterruptedException)tmp;
    		else
    			return (Risorsa)tmp;
            }
    e questo è il run dello skeleton
    codice:
    public void run()
    	{
    		try
    		{
    			while (true)
    			{
    				String op = null;
    				try
    				{
    					op = (String)in.readObject();
    				}
    				catch (SocketException e)
    				{
    					System.out.println("SERVER\tConnessione terminata");
    					break;
    				}
    				if (op.equals("ric"))
    				{
    					int i = ((Integer)in.readObject()).intValue();
    					try
    					{
    						Risorsa r = g.richiedi(i);
    						out.writeObject(r);
    					}
    					catch (GiaAssegnata e)
    					{
    						out.writeObject(e);
    					}
    					catch (InterruptedException e)
    					{
    						out.writeObject(e);
    					}
    				}
    				else if (op.equals("ril"))
    				{
    					int i = ((Integer)in.readObject()).intValue();
    					Risorsa r = (Risorsa)in.readObject();
    					try
    					{
    						g.rilascia(i,r);
    						out.writeObject("OK");
    					}
    					catch (RisorsaErrata e)
    					{
    						out.writeObject(e);
    					}
    					catch (NoRisorsa e)
    					{
    						out.writeObject(e);
    					}
    					catch (NullPointerException e)
    					{
    						;
    					}
    				}
    				else
    				{
    					g.stampaRisorse();
    					out.writeObject("OK");
    				}
    			}
    		}
    		catch (ClassNotFoundException e)
    		{
    			e.printStackTrace();
    		}
    		catch (IOException e)
    		{
    			e.printStackTrace();
    		}
    		finally
    		{
    			try
    			{
    				s.close();
    			}
    			catch (IOException e)
    			{
    				;
    			}
    		}
    	}
    }
    Non saprei perchè succede questa cosa

  6. #6
    Originariamente inviato da francordine
    Non saprei perchè succede questa cosa
    Ma il riferimento di cui tu parli, qual è?
    Poi il problema si verifica lato client o lato server?

    Intanto, ti posso dare un po' di consigli:
    Qui tu scrivi
    Originariamente inviato da francordine
    codice:
    		out.writeObject(new Integer(idUtente));
    quando potresti sfruttare l'autoboxing, scrivendo:
    codice:
    		out.writeObject(idUtente);
    La stessa cosa vale per l'unboxing nel momento in cui leggi.

  7. #7
    Si ho scritto
    codice:
    out.writeObject(new Integer(idUtente));
    perchè il prof in ogni esercizio di questo argomento scrive sempre così

    Se vedi nel run() cè questo pezzo di codice
    codice:
    if (op.equals("ric"))
    				{
    					int i = ((Integer)in.readObject()).intValue();
    					try
    					{
    						Risorsa r = g.richiedi(i);
    						out.writeObject(r);
    					}
                                            ....
    quando leggo l'oggetto dal socket nel metodo dello stub con readObject
    codice:
    try
    		{
    			tmp = in.readObject();
    		}
    		catch (ClassNotFoundException e)
    		{
    			throw new IOException();
    		}
    		if (tmp instanceof GiaAssegnata)
    			throw (GiaAssegnata)tmp;
    		else if (tmp instanceof InterruptedException)
    			throw (InterruptedException)tmp;
    		else
    			return (Risorsa)tmp;
    mi ritrovo un altro riferimento ad un oggetto Risorsa. Dico questo perchè nella classe che implementa l'interfaccia ho messo questo campo statico
    codice:
    public static Risorsa richiesta;
    che mi memorizza il riferimento dell'oggetto che restituisce il richiedi di questa classe.
    Infatti ci ho messo nel suo codice
    codice:
    richiesta = memo[i];
    Non l'ho riportato prima, ma per verificare che i riferimenti siano uguali ho messo un if-else nel richiedi dello stub. Ecco dove l'ho messo:
    codice:
    public Risorsa richiedi(int idUtente) throws GiaAssegnata, InterruptedException, IOException
    	{
    		Object tmp = null;
    		out.writeObject("ric");
    		out.writeObject(new Integer(idUtente));
    		try
    		{
    			tmp = in.readObject();
    		}
    		catch (ClassNotFoundException e)
    		{
    			throw new IOException();
    		}
    		if (tmp instanceof GiaAssegnata)
    			throw (GiaAssegnata)tmp;
    		else if (tmp instanceof InterruptedException)
    			throw (InterruptedException)tmp;
    		else
    		{
    			if ((GestoreRisorseImpl.richiesta) == tmp)
    				System.out.println("Stesso riferimento");
    			else
    				System.out.println("Riferimento diverso");
    			return (Risorsa)tmp;
    		}
    	}

  8. #8
    Il problema è qui:
    Originariamente inviato da francordine
    codice:
    			if ((GestoreRisorseImpl.richiesta) == tmp)
    				System.out.println("Stesso riferimento");
    Penso che il tuo obiettivo sia quello di confrontare i due oggetti e non i riferimenti, poichè in questo caso è scontato che non si può trattare dello stesso riferimento.

    L'operatore == è utilizzato per confrontare riferimenti e tipi primitivi, ma non oggetti/istanze di una o più classi.

    Quindi, devi confrontare i due oggetti utilizzando il metodo equals, che la tua classe Risorsa deve ridefinire.

    Ti ho scritto questo piccolo esempio:
    codice:
    public class Record {
        private int n;
        private String s;
        	
        public Record(int n, String s){
        	this.n = n;
        	this.s = s;
        }
        	
        @Override
        public boolean equals(Object o){
        	if( o == null || !(o instanceof Record) )
        		return false;
        	Record other = (Record)o;
        	
        	return (this.n == other.n && this.s.equals(other.s));
        
        }
        
        public static void main(String args[]){
            Record ref = new Record(1, "stesso oggetto");
            Record selfRef = ref;
            Record otherRef = new Record(1, "stesso oggetto");
            
            System.out.println("ref e selfRef sono lo stesso riferimento -> " + ref + " == " + selfRef + ": " + (ref == selfRef) );
            System.out.println("ref/selfRef e otherRef sono riferimenti diversi -> " + otherRef + " == " + ref + ": " + (otherRef == ref) );
            System.out.println("Ma sono praticamente lo stesso Oggetto:");
            System.out.println(otherRef.equals(ref));
            System.out.println(otherRef.equals(selfRef));
        }
    }
    spero ti sia utile.

  9. #9
    Grazie mille!!!
    Ora ho capito come devo fare. Grazie ancora.

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 © 2024 vBulletin Solutions, Inc. All rights reserved.