Newsgroup: it.comp.java
Titolo: quesito su scope delle variabili

Salve a tutti, una domanda veloce...
 
int [] f(){
 int arr = {1,2};
 return arr;
}
 
è corretto?
Grazie


no.
 
ps: se il codice non compila ci puoi mettere la mano sul fuoco che non 
sia corretto, anche senza chiedere.
 
ps2: lo scope di preciso cosa c'entrerebbe?
 

il 05.04.2013 16:45, Scrive Boe Szyslak 278577676:

A compendio di quanto asserito da rootkit:
non e' corretto in quanto:
- l'assegnazione int arr = {1,2}; non e' valida poiche' il tipo a 
sinistra di = non e' compatibile co quello di destra
- il tipo ritornato 'int' non e' compatibile con il tipo dichiarato 'int[]'
Permangono i dubbi in merito allo scope.
 

> Permangono i dubbi in merito allo scope.
 
Scusate, ho sbagliato a scrivere il codice nel post
 
quello che intendevo è
 
 int [] f(){
   int[] arr = {1,2};
   return arr;
 } 
 
I miei dubbi sullo scope riguardano il fatto che che arr viene creato dentro f, e dovrebbe morire quando f ritorna.
Ho fatto delle prove pratiche e sembra funzionare, ma volevo essere sicuro (anche perchè l'equivalente in c++ è errato)

il 08.04.2013 17:28, Scrive Boe Szyslak 224671676:

Funziona proprio così. Quando in Java crei un oggetto (quindi anche un 
array di primitivi come int[]) il suo riferimento viene conservato 
finche' l'oggetto non e' piu' referenzaito da alcuna classe.
quindi se:
 
void metodo test() {
	int[] array = f();
	return;
}
 
arr muore quando test() finisce, mentre:
 
class Prova {
   int[] array;
   void metodo test() {
	array = f();
	return;
   }
...
}
in tal caso arr muore quando saranno morti tutte le istanze della classe 
Prova.
In C++ (ma anche in C) un array ha il suo puntatore, se non lo crei in 
una zona statica, lo spazio a cui punta puo' essere riassegnato in ogni 
momento.
 

 sicuro (anche perchè l'equivalente in c++ è errato)
 
in che senso?
 

Ma quindi se q questo punto avessi un'istruzione tipo
 
int [] a = f();
 
cosa succederebbe?
la variabile a sarebbe un nuovo oggetto con i valori uguali a arr contenuto in f (cioè avverrebbe una copia profonda) o ci sarebbe un dangling pointer come avverrebbe in c++?

 la variabile a sarebbe un nuovo oggetto con i valori uguali
 > a arr contenuto in f (cioè avverrebbe una copia profonda)
 > o ci sarebbe un dangling pointer come avverrebbe in c++?
 
Nessun dangling pointer, soprattutto perché in Java non è possibile 
deallocare o cancellare oggetti in memoria senza passare per i 
riferimenti agli oggetti stessi.
La variabile /a/ contiene il valore che, all'interno della funzione /f/, 
aveva /arr/. Quindi sì: una copia, del valore del riferimento.
 
Visto che citi i puntatori (in C / C++) ti suggerisco di notare come il 
passaggio di parametri (sia in ingresso che uscita dal metodo) avvenga 
sempre per valore, ma sapendo che questo valore può anche essere il 
riferimento all'oggetto (eccetto per i tipi di dato primitivi).
Cosa che può "emulare" un passaggio per riferimento.
Qui trovi degli ottimi esempi: 
http://javadude.com/articles/passbyvalue.htm
 
 
Se non ho mal interpretato il fine ultimo della tua domanda :)
 
P.
 

quindi, se non ho capito male l'assegnazione fra array in java funziona per valore quando la variabile "a destra" viene restituita da una funzione (viene fatto una specie di "clone" dell'array, mentre negli altri casi avviene per riferimento.
 
infatti
 
int[] a = {1,2};
int[] b = a;
b[0] = 0;
System.out.println (a[0]);
 
stampa 0.
 
Correggetemi se sbaglio...

 Correggetemi se sbaglio...
 
Spero di avere un po' chiarito il discorso, per sintetizzarlo possiamo 
citare Gosling, che un po' di Java lo conosce ;) , quando ribadisce che 
in Java _tutto_ viene passato per valore.
Poi va tenuto conto del fatto che il valore passato a volte (spesso!) 
contiene un riferimento, ossia il puntatore all'oggetto 
(
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.3.1
 
seconda riga).
 
Concludendo: attenzione che se crei un metodo "cambia(qualcosa)"
hai un comportamento diverso a seconda del tipo di dato di "qualcosa" 
(oggetto, primitivo, oggetto immutabile) e da quello che fai all'oggetto 
(es. ulteriori copie).
Per evitare equivoci conviene sempre fare in modo che il metodo 
restituisca la copia modificata di "qualcosa".
 
P.
 

 (es. ulteriori copie).
 
A questo punto desumo che l'array dichiarato in un blocco sia trattato come un oggetto qualsiasi (si comporta come l'arrayList del tuo esempio), mentre l'array ritornato da una funzione sia di tipo immutabile (e quindi si comporta come una String).
Ho capito bene?
Grazie!!


no non è immutabile. un oggetto immutabile non ha metodi o proprietà 
modificabili mentre gli elementi dell'array li puoi modificare.
 
ricapitolando:
 
- la funzione crea al suo interno una istanza di tipo array di int
- gli array sono oggetti
- l'istanza di array ritornata dalla funzione è la stessa
- relativamente allo scope, terminata la funzione muore la reference ma 
non l'istanza dell'array
 
prendendola con le dovute cautele del caso, il contesto è simile ad una 
funzione c che alloca e ritorna un puntatore a int.   
 

 non l'istanza dell'array
 
Quindi, a livello teorico è lo stesso che fare 
 
  int [] f(){
    int[] arr = new int[2];
    arr[0] = 1; 
    arr[1]=2;
    return arr;
 } 
 
o no?
 
 

il 11.04.2013 16:33, Scrive Boe Szyslak 218285948:

vero