|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
[Questione filosofica] In java esiste il passaggio per riferimento?
Continuazione della discussione iniziata in questo thread:
http://www.hwupgrade.it/forum/showthread.php?t=1363275 dal post numero 12. ____________________________ Riassumo: In molti (tutti?) libri di java, in documentazione on line, eccetera è scritto che in java gli oggetti vengono passati per riferimento (in invocazioni locali). Per alcuni invece - vedi il sito http://www.yoda.arachsys.com/java/passing.html insieme a molti altri che potrete trovare con google - java supporta solamente il passaggio per valore. Come si evince dall'altro thread la mia opinione (?), per ora, è Codice:
risposta = "SI"; In pratica io sono convinto che le ragioni esposte in particolare nel sito sopra non stiano in piedi, per il motivo che - vedi il primo esempio citato nel sito - se io assegno alla referenza (parametro formale) l'indirizzo di un altro oggetto non ha più senso chiedersi se tale oggetto è stato passato per valore o per riferimento, in quanto si è solo modificato il valore del riferimento - che è != dall'oggetto, passato per riferimento. Altra idea: per distinguere il passaggio per riferimento da quello per valore considero la "trasparenza" o meno del riferimento - ad esempio il C supporta solo passaggio per valore, in quanto dicendo *x uso esplicitamente il puntatore per accedere alla variabile. Contorto, eh? Aspetto altri spunti di discussione... ![]()
__________________
|Java Base| |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Dec 2002
Città: Milano
Messaggi: 5062
|
Il discorso è semplicissimo.
In java ci sono i tipi primitivi (int, float,..) ed i tipi "classe", ovvero riferimento ad oggetti. Il passaggio di parametri viene fatto sempre per valore, ovvero viene sempre copiato il valore del tipo primitivo o del riferimento. Le variabili dichiarate come classe sono tutte "puntatori" ad istanze di oggetti, quindi ovviamente nel passaggio l'istanza non viene duplicata... Perciò la situazione di passaggio di tipi classe è molto simile nel C al passaggio tramite puntatore. Ultima modifica di subvertigo : 22-12-2006 alle 23:22. |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Guarda ... poco tempo fa c'è stato un thread che parlava del passaggio di parametri in C/C++. In quel thread avevo postato anche io dicendo che in "C" il passaggio di parametri può avvenire per valore o per riferimento. Affermazione che ritengo tuttora valida, nonostante in quel thread diverse altre persone sostenessero che in "C" esiste solo il passaggio per valore. Poi non avevo più postato in quel 3d ... perché non volevo innescare chissà quale flame o cose del genere. Insomma sono uno a cui non piace scocciare o rompere le scatole alla gente.
Comunque si può fare un paragone tra C e Java, per capire il perché ritengo che in "C" ci sia il passaggio per riferimento mentre in Java no. In Java esiste solo ed esclusivamente il passaggio per valore. Se ho una variabile primitiva (int, char ...) e la passo ad un altro metodo, passo una copia del valore. Allo stesso modo, se ho una variabile di tipo reference che fa riferimento ad un oggetto, passo al metodo una copia del reference, cioè una copia del valore contenuto nel reference. Adesso viene il bello: se nel 'metodoA' ho una variabile di un qualunque tipo (primitivo o reference), secondo voi posso passarla in un qualche modo al 'metodoB' in modo tale che esso possa alterare il valore della variabile nel metodoA??? No, non è possibile. Per questo Java ha solo il passaggio per valore. Invece in "C" è diverso. Se nella 'funzioneA' ho una variabile (di un qualunque tipo), posso passare alla 'funzioneB' un riferimento alla variabile (il suo indirizzo) in modo tale che il metodoB possa alterare il valore della variabile. Ecco perché il "C" ha passaggio per valore e per riferimento mentre Java ha solo il passaggio per valore. Tutto questo IMHO ... ora non massacratemi come nell'altro thread ... ![]()
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
bhè...
la risposta nonostante le tua opinione è cmq "NO". E questo non perchè lo dico io ma perchè l'ha detto quello ke vienie considerato il padre di java. Come ho già detto ho partecipato (o meglio... ho lurkato ![]() Lì furono postati diversi articoli e se non sbaglio ache riferimenti ad un libro scritto dal suddetto (di cui ora mi sfugge il nome ![]() Cmq anke senza il "riconoscimento ufficiale" di cui sopra la risposta è cmq NO ![]() Hai provato a utilizzare il codice ke ho postato nell'altra discussione? Se in java il passaggio fosse per riferimento allora non avresti alcun problema a generare una funzione void swap(obj1, obj2) come puoi fare in C utilizzando il passaggio per riferimento... Però in java, come hai visto dall'esecuzione del codice ke ho postato (e ke ovviamente devi integrare in una classe Point ![]() Questo perchè tu non stai lavorando sulle reference originali degli oggetti ma solo su copie di esse. Dunque anke il comportamento a livello di codice è completamente diverso rispetto al classico passaggio x riferimento, tanto x non dare adito ad alcun dubbio ![]()
__________________
![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Ho appena scoperto ke sul forum della sun hanno cancellato il thread aperto da DeFi in cui si parlava di questo
![]()
__________________
![]() |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Quote:
![]() Comunque, ritornando al problema... Voi dite: "i riferimenti vengono passati per valore" E io dico: fisicamente il passaggio per valore è l'unico possibile - anche i puntatori sono valori - e allora o il passaggio per riferimento non esiste oppure fatemi un esempio di vero passaggio per riferimento in cui i puntatori o referenze o quant'altro non siano passati per valore. Il senso del discorso che facevo prima è che il sito sopra, nello specifico nel primo esempio, "gioca sporco" perché modifica i puntatori tramite assegnamento - non per nulla per confrontare 2 oggetti non si usa == o !=, bensì il metodo equals, perché l'oggetto non è il suo puntatore, ma ciò che è puntato da esso, su cui si opera *esclusivamente* con metodi, o con assegnamenti ai suoi *campi*. Il fatto che in java non funzioni una swap tra primitivi o tra riferimenti è dovuto al fatto che questi sono appunto valori. Ma gli oggetti, quelli "veri", sono un'altra cosa, e si potrebbe pure fare uno swap, se i metodi dell'oggetto lo consentono.
__________________
|Java Base| |
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Sep 2004
Città: Interamnia Urbs
Messaggi: 2125
|
Quote:
__________________
Un wormhole (buco di tarlo, in italiano), detto anche Ponte di Einstein-Rosen, è una ipotetica caratteristica topologica dello spaziotempo che è essenzialmente una "scorciatoia" da un punto dell'universo a un altro, che permetterebbe di viaggiare tra di essi più velocemente di quanto impiegherebbe la luce a percorrere la distanza attraverso lo spazio normale. Go to a Wormhole |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Quelli puntati dalle reference, e non le reference stesse, che sono alias
per oggetti, che possono essere riassegnate eccetera. Un altro articolo che sostiene l'assenza del passaggio per rif. in java è questo: http://www-128.ibm.com/developerwork...y/j-passbyval/ A un certo punto si confronta l'approccio C++ con quello Java, nei listing 6 e 7. Quel confronto funziona semplicemente perché le reference in C++ sono costanti (vero? mi viene ora il dubbio), e quindi non si può fare il giochetto - usato ad esempio nel primo sito citato - di scambiare le reference. Lo stesso effetto si può ottenere in java con il passaggio a volte detto "per costante": void tricky(final Point arg1, final Point arg2) { ... }
__________________
|Java Base| |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Ancora una cosetta, poi spengo perché devo uscire...
Vorrei cercare di far capire una cosa un po' astratta. Consideriamo la seguente funzione C++: void Func(int& a) { a++; } Ora dichiaro un "oggetto" intero - passatemi il termine: int n = 10; Pensate al nome 'n' come a un riferimento all'oggetto '10' La funzione: Func(n); accede all'oggetto '10' mediante il riferimento 'a', lo modifica (pensate all'operatore ++ come a un metodo), e questa modifica è visibile all'esterno della funzione. Ecco, io non vedo differenza tra questo approccio e quello di java per gli oggetti locali. Non sto dicendo di aver ragione, solo che non riesco a convincermi, abbiate pazienza... ![]()
__________________
|Java Base| |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Mi siete testimoni, io ho provato ad essere sintetico
![]() Credo che qui non sia in discussione se Java e C possiedano o no il "passaggio per riferimento", cosa che è per entrambi, non simili ma identici sotto questo profilo, preclusa dalle specifiche dei rispettivi linguaggi. Ogni libro che reciti il fatto che in Java qualcosa sia passato per riferimento è evidentemente scritto da chi non abbia mai letto o abbia mal interpretato le specifiche del linguaggio. Da notare che la svista ha un autorevole precursore. Fu infatti un documento di Sun Microsystem, rilasciato insieme alla piattaforma Java 1.1, il primo a dire che esisteva una diversità tra il passaggio di una variabile riferimento e quello di una variabile di tipo primitivo. Affermazione fortemente smentita da Gosling, Arnold e Holmes ed evidentemente contraddetta nelle specifiche del linguaggio (si veda ad esempio 8.4.1, "Quando il metodo o il costruttore è invocato il valore delle espressioni, argomenti attuali [dell'invocazione] è usato per inizializzare delle variabili parametro di nuova creazione" o 15.12.4.5, dove al frame di attivazione sono attribuiti "i valori degli argomenti") Credo invece che la questione riguardi la definizione di "passaggio di una variabile ad una funzione". La definizione consueta di passaggio di una variabile è semplicissima è dice che passaggio della variabile v alla funzione f significa uso di v come parametro di f. Quando andbin dice che in C se ho una variabile v posso passare alla funzione f l'indirizzo di quella variabile e ottenere il passaggio per riferimento assume una diversa definizione di "passaggio di una variabile ad una funzione". Non è v ad essere usata come argomento di f ma è una diversa variabile v', correlata a v dal contenere v' l'indirizzo di v. Io penso che questa diversa definizione di "passaggio di una variabile ad una funzione" sia non già "l'uso di v come argomento di f" ma la "applicazione di f al valore di v", a prescindere dal fatto che v sia o non sia usata come argomento di f. Per quanti pensino che ridefinire un concetto sia errato ricordo, nel modo più cordiale possibile, che ogni teoria si appoggia ad una o più di questi artifici, tanto che essi sono stati a loro volta "nominati". Si chiamano definizioni speculative di Lesniewsky. Per i masochisti, la nuova definizione che qui stiamo creando non è applicabile allo stesso ambito della vecchia perchè nella teoria (T) della vecchia definizioen (D) la nuova definizione (D') diventa creativa. Cioè data una proposizione S indimostrabile in T (che il passaggio della tal variabile v avvenga per riferimento) esiste una proposizione S' risultante dall'applicazione di D', giudicata equivalente ad S che risulta stavolta dimostrabile in T. Cioè per la vecchia definizione, una teoria dava una certa proposizione come falsa (che il passaggio di v avvenga per riferimento). Applicando la nuova definizione quella proposizione essa diventa vera (il passaggio di v è per riferimento). Non funziona, si dice che la definizione in T è creativa e quindi viola il secondo limite di Lesniewsky (la non creatività, l'altro è la sostituibilità che mi pare rispettata) Non funziona ma in quella teoria. Potrebbe anche andare benissimo in una diversa teoria. A naso c'è qualcosa che mi suona bene ma non è mia, non posso tentare di giustificarne l'utilità dall'esterno.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! Ultima modifica di PGI-Bis : 23-12-2006 alle 17:52. Motivo: svarioni |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
![]() ma l'hai provato il codice ke ho postato? ![]() no..xkè provandolo ti accorgeresti che non ti farebbe nemmeno compilare perchè stai tentando di modificare una reference ke è dichiarata final e qdi costante. Quindi come vedi lo swap definito come metodo void non ha modo di funzionare in java per quanto tu ti possa sforzare a trovare un qualsiasi artificio xkè semplicemente il passagio x riferimento in java non esiste ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
![]() era Gosling a cui mi riferivo io se non ricordo male ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Ma, sai, il problema del chi l'ha detto è sempre relativo. Il nome aggiunge autorevolezza il che rende l'affermazione, appunto, autorevole: ma nulla vieta che sia una stupidaggine. Noi dobbiamo - o dovremmo - guardare a come è definito il linguaggio e verificare se il rispetto di quella definizione ci consenta o non ci consenta di introdurre la caratteristica di cui discutiamo. A mio parere nè C nè Java consentono di dire che in essi esista il passaggio per riferimento, secondo la definizione comune di passaggio.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
io ho citato lui perchè era intervenuto nella discussione ke lurkavo..e xkè essendo stato uno dei padri di java immagino sapesse ciò di cui parlava. Ma cmq la verifica da codice non ha lasciato adito a dubbi ![]() X il C onestamente non ho idea se si possa dire ke usi il passaggio x riferimento o no xkè nn lo conosco a fondo come java.. so solo ke & dovrebbe passare il riferimento di un oggetto mentre * il puntatore... e in effetti la funzione swap in c funziona perfettamente utilizzando &... qdi....ora tocca a me fare la domanda...xkè nemmeno in C non esiste il passaggio x riferimento? ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Quote:
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Dec 2005
Messaggi: 7249
|
Quote:
Codice:
private void WaitForAnswer(ref String obj, int timeout) { int index = 0; while(obj==null & ++index<timeout) { Thread.Sleep(1); } if(obj==null) onErrorEvent(this, new ErrorEventArgs("Timeout waiting answer")); } ![]() |
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Sep 2004
Città: Interamnia Urbs
Messaggi: 2125
|
mi sta venendo un dubbio, qualcuno mi può dare la definizione ufficiale di "passaggio per riferimento"? Non riesco a trovarla.
__________________
Un wormhole (buco di tarlo, in italiano), detto anche Ponte di Einstein-Rosen, è una ipotetica caratteristica topologica dello spaziotempo che è essenzialmente una "scorciatoia" da un punto dell'universo a un altro, che permetterebbe di viaggiare tra di essi più velocemente di quanto impiegherebbe la luce a percorrere la distanza attraverso lo spazio normale. Go to a Wormhole |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
![]() ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Dec 2005
Messaggi: 7249
|
Quote:
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:28.