Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Ricerca personalizzata

[Java] Dubbio passaggio per riferimento

Linguaggi e sistemi

Moderatore: Foto UtentePaolino

0
voti

[1] [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtentePatras » 25 ago 2017, 16:08

Ciao a tutti! Ho appena fatto un esercizio e mi sorge il dubbio riguardo al passaggio per riferimento in java.
Quando ho un oggetto per esempio del tipo Node (nodo di una lista) e faccio qualcosa del genere:
Codice: Seleziona tutto
static void metodo(LinkedList listOne)
{
   Node<T> s = new Node<T>();
   u = listOne.getFirst();
   getK( u ,...., s );
   String parola = s.getElement(); //contiene quella del decimo di ListOne??
}
static void <T> getK( Node<T> v,... , Node<T> nk )
{
   for(int i=0; i<10; i++)
      v=v.getNext();
   nk=v;
}

Ora s punta al decimo nodo della listOne? ciò nonostante il fatto di aver passato s come parametro?
Avatar utente
Foto UtentePatras
25 4
New entry
New entry
 
Messaggi: 54
Iscritto il: 24 mag 2017, 14:27

1
voti

[2] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtenteAjeieBrazov » 25 ago 2017, 16:35

Gli oggetti vengono sempre passati come riferimenti.
Se non vuoi alterare un oggetto devi farne una copia.
Avatar utente
Foto UtenteAjeieBrazov
971 3 7
---
 
Messaggi: 410
Iscritto il: 23 mag 2017, 20:53

0
voti

[3] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtentePatras » 25 ago 2017, 16:41

quindi mi pare di capire che no, perché ora nk punta a v[10] ma s non punta a nk... s rimane quello di prima.

A sto punto mi chiedo ma non esiste davvero un modo per risolvere questo? Nel mio caso per esempio...
in C se non sbaglio basta mettere una & davanti al parametro...
Avatar utente
Foto UtentePatras
25 4
New entry
New entry
 
Messaggi: 54
Iscritto il: 24 mag 2017, 14:27

1
voti

[4] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtenteAjeieBrazov » 25 ago 2017, 16:46

In Java l'oggetto "fisico" risiede nel heap, quello che viene assegnato alla variabile di tipo oggetto è sempre e solo il puntatore all'indirizzo del heap dove l'oggetto è memorizzato.
E' come se lavorassi in C usando (quasi) solo puntatori. Se passi un puntatore e modifichi la variabile da esso puntata la modifichi in modo permanente.
In Java solo i tipi primitivi vengono passati per valore.
Avatar utente
Foto UtenteAjeieBrazov
971 3 7
---
 
Messaggi: 410
Iscritto il: 23 mag 2017, 20:53

1
voti

[5] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto Utentewruggeri » 25 ago 2017, 16:49

Java non permette il passaggio per riferimento: qualsiasi parametro Java è passato by value.

Precisamente: tutti gli oggetti in Java sono indicati tramite puntatori: se esegui l'istruzione

Codice: Seleziona tutto
String s = new String()


Crei un nuovo oggetto, e dichiari di voler usare l'identificatore s per riferirti a lui. Ora, se tu passi s come parametro alla funzione

Codice: Seleziona tutto
void change(String sl)
{
    String k = "Ciao";
    sl = k;
    return;
}


Quello che succede è che tu passi alla funzione un puntatore il cui valore è stato ricopiato in un altro puntatore. Ora, quando tu effettui l'assegnamento
Codice: Seleziona tutto
sl = k


Quello che stai facendo è sostanzialmente cambiare il valore del puntatore, ovvero stai dicendo al tuo programma "prendi il puntatore sl e mettici dentro il valore del puntatore k", ovvero ancora stai cambiando l'oggetto cui il tuo puntatore sl punta, ma non stai modificando assolutamente l'oggetto cui puntava prima.

Tutto chiaro? ;-)


Già che ci siamo: per convincerti di ciò che dico, prova ad eseguire questo codice:

Codice: Seleziona tutto
   public static void change(String ls)
   {
      String k = new String("Prova");
      
      System.out.println("INIZIO: ls = " + ls);
      
      ls = k;
      
      System.out.println("FINE: ls = " + ls);
      
      return;
   }
   
   public static void main(String args[])
   {
      String s;
      
      s = new String("Ciao");
      
      change(s);
      
      System.out.println("s = " + s);
   }
Si, nei limiti delle mie capacità ti rispondo... ma per favore, impara l'italiano!
Se non conosci un argomento, non parlarne.
Gli unici fatti scientifici sono quelli accertati dagli studi. Il resto è opinione.
GATTINI A TORINO
Avatar utente
Foto Utentewruggeri
2.368 1 5 13
Expert EY
Expert EY
 
Messaggi: 448
Iscritto il: 25 nov 2016, 17:46

1
voti

[6] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtenteAjeieBrazov » 25 ago 2017, 17:18

Codice: Seleziona tutto
public class Persona {
  public String nome;
  public String cognome;
  public Persona(String nome, String cognome) {
    this.nome = nome;
    this.cognome = cognome;
  }
  @Override
  public String toString() {
    String s = "Nome: " + this.nome + "\nCognome: " + this.cognome;
    return s;
  }
}


Codice: Seleziona tutto
public class Prova {
  private static void cambia(Persona p) {
    p.cognome = "sempronio";
  }
  public static void main(String[] args) {
    Persona p = new Persona("tizio","caio");
    System.out.println(p);
    cambia(p);
    System.out.println(p);
  }
}


Output
Codice: Seleziona tutto
Nome: tizio
Cognome: caio
Nome: tizio
Cognome: sempronio


Magari è solo una questione di terminologia ma mi hanno insegnato che questo è un passaggio per riferimento, nel senso che non passi il valore dell'oggetto ma il riferimento all'oggetto.
Avatar utente
Foto UtenteAjeieBrazov
971 3 7
---
 
Messaggi: 410
Iscritto il: 23 mag 2017, 20:53

0
voti

[7] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtentePatras » 25 ago 2017, 17:37

Grazie mille siete stati chiarissimi :ok:
Avatar utente
Foto UtentePatras
25 4
New entry
New entry
 
Messaggi: 54
Iscritto il: 24 mag 2017, 14:27

1
voti

[8] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto Utentewruggeri » 25 ago 2017, 17:50

Purtroppo la differenza è sottile e non viene mai spiegata bene, perché tutti i docenti di informatica passano mesi a mostrare listati infiniti e imbottire gli studenti di frammenti di codice già pronti ma nessuno perde un paio di giorni a spiegare cosa davvero vogliano dire le righe di codice...

La parola d'ordine è evaluation strategy, ovvero "come e quando i linguaggi valutano i parametri di una funzione".
Senza dilungarci troppo, ci sono linguaggi (come C o Java) che valutano i parametri sempre e soltanto by value, ovvero (semplificando all'estremo) assegnano il valore dei parametri a delle variabili locali della funzione chiamata; in sostanza, quando tu passi un puntatore ad una funzione C, per il compilatore tu non stai passando un riferimento ad una variabile, bensì stai passando il valore di un puntatore (tra l'altro, in C il puntatore a dato è un tipo a sè stante... ma non divaghiamo).
Altri linguaggi, come se ben ricordo il C# e FORTRAN, permettono invece (anzi, siamo precisi: C# permette, FORTRAN impone) il passaggio by reference, ovvero (sempre semplificando all'estremo) effettuano il passaggio di parametri fornendo alla funzione un riferimento alla specifica locazione di memoria in cui risiede il dato usato come parametro al momento della chiamata.
[Ci sono anche altre strategie di valutazione, ma non le tratto per non perdere tempo]

Come avrai intuito, certi linguaggi che usano il passaggio per valore possono "simulare" il passaggio per riferimento (il C lo fa con il passaggio dei puntatori, ad esempio), e per il programmatore quadratico medio più o meno il risultato è equivalente ad un vero e proprio passaggio by value... ma non è così: i compilatori sono progettati in modo tale da analizzare ed ottimizzare il codice secondo le specifiche del linguaggio, per cui è possibile che la simulazione di un passaggio by reference sia meno efficiente di un vero passaggio by reference, o addirittura la simulazione potrebbe risultare (a me non è mai capitato, ma in linea di principio è possibile) in qualche errore che il compilatore potrebbe non rilevare correttamente.
Si, nei limiti delle mie capacità ti rispondo... ma per favore, impara l'italiano!
Se non conosci un argomento, non parlarne.
Gli unici fatti scientifici sono quelli accertati dagli studi. Il resto è opinione.
GATTINI A TORINO
Avatar utente
Foto Utentewruggeri
2.368 1 5 13
Expert EY
Expert EY
 
Messaggi: 448
Iscritto il: 25 nov 2016, 17:46

0
voti

[9] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtentePatras » 25 ago 2017, 21:57

Grazie mille per la dettagliata descrzione
wruggeri ha scritto:Come avrai intuito, certi linguaggi che usano il passaggio per valore possono "simulare" il passaggio per riferimento (il C lo fa con il passaggio dei puntatori, ad esempio)

Si ma credevo che riuscissero a renderla molto veloce ottimizzando magari i codici del livello più basso (tipo assembly). Grazie per avermi avvisato.

Infatti per la mia esperienza da studente posso dirti che hai perfettamente ragione. Continuavano a dirci che il passaggio è "per riferimento" parlando degli oggetti, discorso che stava in piedi fino a un certo punto quando arrivi ai parametri del metodo dove bisogna approfondire un attimo. Leggendo anche su qualche sito internazionale trovavo "passed by value, but the value is a reference" che mi ha confuso di nuovo.
Comunque ora ho capito tutto grazie alle vostre spiegazioni. :ok:
Avatar utente
Foto UtentePatras
25 4
New entry
New entry
 
Messaggi: 54
Iscritto il: 24 mag 2017, 14:27

1
voti

[10] Re: [Java] Dubbio passaggio per riferimento

Messaggioda Foto UtenteAjeieBrazov » 25 ago 2017, 22:03

Mi permetto un suggerimento: hai occasione di studiare il Java, quindi studialo bene. Adoro il Java perché è, a mio avviso (e qui mi tirerò dietro le ire di molti) è semplicemente una genialata.
Per lavoro programmo (quasi) sempre in C ma quando ho la necessità di scrivere una utilty che giri su PC uso il Java, e mi diverto tantissimo (non ostante i 30 e più anni di codice scritto per lavoro). ;-)
Avatar utente
Foto UtenteAjeieBrazov
971 3 7
---
 
Messaggi: 410
Iscritto il: 23 mag 2017, 20:53


Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite