Torna indietro   Hardware Upgrade Forum > Software > Programmazione

iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile
iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile
C'è tanta sostanza nel nuovo smartphone della Mela dedicato ai creator digitali. Nuovo telaio in alluminio, sistema di raffreddamento vapor chamber e tre fotocamere da 48 megapixel: non è un semplice smartphone, ma uno studio di produzione digitale on-the-go
Intel Panther Lake: i processori per i notebook del 2026
Intel Panther Lake: i processori per i notebook del 2026
Panther Lake è il nome in codice della prossima generazione di processori Intel Core Ultra, che vedremo al debutto da inizio 2026 nei notebook e nei sistemi desktop più compatti. Nuovi core, nuove GPU e soprattutto una struttura a tile che vede per la prima volta l'utilizzo della tecnologia produttiva Intel 18A: tanta potenza in più, ma senza perdere in efficienza
Intel Xeon 6+: è tempo di Clearwater Forest
Intel Xeon 6+: è tempo di Clearwater Forest
Intel ha annunciato la prossima generazione di processori Xeon dotati di E-Core, quelli per la massima efficienza energetica e densità di elaborazione. Grazie al processo produttivo Intel 18A, i core passano a un massimo di 288 per ogni socket, con aumento della potenza di calcolo e dell'efficienza complessiva.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 05-11-2004, 15:03   #1
gokan
Senior Member
 
L'Avatar di gokan
 
Iscritto dal: Apr 2002
Città: Palermo
Messaggi: 4913
[JAVA] Parola chiave " this "

Salve ragazzi, premetto che sto tentanto di imparare il java ed in generale la filosofia della programmazione ad oggetti. Sto studiando sul testo Thinking in Java di Bruce Eckel. Ho difficoltà a capire per bene l'uso della parola chiave this. Mi riferirò all'esempio del testo (perchè prima di spiegare l'uso di this, l'autore compie la premessa che sto per scrivervi), vediamo se mi aiutate voi a chiarire
L'autore inizia così in breve:

Se avete due oggetti dello stesso tipo a e b, potreste chiedervi come è possibile che si possa chiamare un metodo f() per entrambi gli oggetti.

Poi fa l'esempio
Codice:
class Prova {
  void f(int i) {/*..... */}
}

Prova a =new Prova(), b =new Prova();

a.f(1);
b.f(2);
L'autore prosegue poi:
Se c'è un solo metodo chiamato f(), come può quel metodo sapere se è stato chiamato per l'oggetto a o b?


Non capisco perchè l'autore si pone questo problema, non è un operazione lecita? La chiamata
a.f(1)
che problema può creare?

Mi potete spiegare questa cosa?
L'autore dice che effettivamente il compilatore è come se facesse una chiamata del tipo (non scrivibile in questo modo però):
Prova.f(a,1) //al posto di a.f(1)

Non capisco il significato di tutte questo lavoro, non ho capito ancora dove sta il problema

Scusate la lunghezza e grazie
__________________
Sun Certified Java Programmer - Sun Certified Web Component Developer - Sun Certified Business Component Developer
gokan è offline   Rispondi citando il messaggio o parte di esso
Old 05-11-2004, 15:45   #2
anx721
Senior Member
 
L'Avatar di anx721
 
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
Un metodo (non statico) lavora con l'istanza su cui è invocato. Ad esempio, supponi che la tua classe Prova contenga una stringa, e crei un primo oggetto a1 che contiene la stringa "uno", e un secondo oggetto a2 che contiene la stringa "due". Supponi infine che il metodo f() si limiti a stapare la stringa.

a1.f() provocherà la stampa di "uno"

mentre

a2.f() provocherà la stampa di "due"

proprio perche un metodo lavora con le variabili dell'oggetto su cui è invocato.

Se paragoni un metodo alle funzioni globali del C, puoi notare che in java invochi un metodo su un pggetto con la sintassi

oggetto.metodo();

mentre in C solitamente avrai una variabile oggetto che passi come argomento della funzione:

metodo(oggetto)


In realtà questo è anche ciò che avviene con la programmazione ad oggetti, perche quando in java invochi un metodo su un oggetto:

oggetto.metodo(....);

il compilatore è come se lo trasformasse in

metodo(oggetto, ....)

proprio perche il metodo deve sapere qualè l'oggetto su cui è stato invocato.
__________________
Sun Certified Java Programmer
EUCIP Core Level Certified

European Certification of Informatics Professionals
anx721 è offline   Rispondi citando il messaggio o parte di esso
Old 05-11-2004, 19:34   #3
gokan
Senior Member
 
L'Avatar di gokan
 
Iscritto dal: Apr 2002
Città: Palermo
Messaggi: 4913
grazie Piè adesso è più chiaro il fatto della chiamata del metodo come intendeva Eckel.
Faccio un altro esempio:
Codice:
public class Leaf {
	int i=0;
	
	Leaf increment() {
		i++;
	 	return this; /////////////////
	}
	
	void print() {
		System.out.println("i= " + i);
	}

public static void main(String args[]) {
	Leaf x= new Leaf();
	
	x.increment().increment().increment().print();
 }	
}   //ritorna i=3
Il return this nel metodo Leaf serve ovviamente per potere ritornare un riferimento all'oggetto per il quale chiamo il costruttore.
Effettivamente mi stavo perdendo in un bicchiere d'acqua

Adesso devo approfondire l'uso di this nella fase di chiamata di costruttori all'interno di altri costruttori. Se dovessi avere prob mi faccio risentire.
Da quanto ne ho capito this è molto utilizzato nel caso in cui si usano dei costruttori, giusto?

Ciao
__________________
Sun Certified Java Programmer - Sun Certified Web Component Developer - Sun Certified Business Component Developer
gokan è offline   Rispondi citando il messaggio o parte di esso
Old 05-11-2004, 20:45   #4
anx721
Senior Member
 
L'Avatar di anx721
 
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
this rappresenta il riferimento all'oggetto corrente, cioè su cui è stato invocato il metodo in esecuzione;

x.increment()

ritorna proprio x stesso perche increment è invocato su x e all'interno di increment si ritorna l'oggetto su cui è in esecuzione il metodo stesso.


In java per invocare un metodo su un oggetto utilizzi la sintassi

oggetto.metodo();

se non indichi l'oggetto, cioè se scrivi solo:

metodo();

allora è come se metodo() venisse invocato sull'oggetto corrente.

Esempio:

Codice:
	Leaf increment() {
		i++;
		print();
	 	return this; /////////////////
	}
in questa versione di increment puoi notare che ho aggiunto la chiamata a print() all'interno del metodo; ma su chi è invocato print? Non ho usato la normale notazione oggetto.print(). Ma la regola che ho detto prima è che se un metodo non è invocato su un oggetto è come se lo invoco sull'oggetto corrente, ovvero l'oggetto su cui è stato invocato increment(); quindi se scrivo:

x.incremet();

durante l'esecuzione di increment, quando si arriva alla chiamata di print(), print sarà chiamata su x, che è l'oggetto corrente.


this raprpesenta proprio l'oggetto corrente; cosi ad esempio, la seguente versione di increment è del tutto equivalente alla precedente:

Codice:
	Leaf increment() {
		i++;
		this.print();
	 	return this; /////////////////
	}

qui ho semplicemente reso escplicito il fatto che print lo sto esegunedo sull'oggetto corrente, anche se di norma non si usa questa sintassi.


Quando allora si usa this, se tanto lo si puo omettere? Alcuni casi sono i seguenti:

- ho un argomento di un metodo che ha lo stesso nome di un campo della classe; esempio:

supponi che la classe Leaf abbia un metodo

setta(int a);

che serve a dare al campo "i" della classe Leaf il valore di a:

Codice:
public setta(int a){
	i = a;
}
tutto ok. Che c'entra this? E' presto detto: immagina di cambiare il prototipo del metodo in:

public setta(int i)

come puoi notare in questo caso l'argomento del metodo ha lo stesso nome del campo "i" della classe; questo significa che il metodo diventa:

Codice:
public setta(int i){
	i = i;
}
in particolare hai l'istruzione

i = i;

in cui stai assegnando al primo "i" che raprpesenta il campo, il valore dell' "i" che è l'argomento. Queste almeno sarebbero le intenzioni; ma il compilatore non è in grado di conoscere le tue intenzioni e sapere quale "i" rappresenta il campo e quale invece l'argomento. Se l'argomento di un metodo ha lo stesso nome di un campo di classe, allora all'interno del metodo l'argometno OSCURA il campo di classe; all'interno del metodo setta(int i), con "i" puoi solo indicare l'argomento; come si fa allora ad indicare il campo "i" di Leaf e non l'argomento? La risposta l'avrai intuita:

this.i

quindi il modo corretto di scrivere il metodo setta è:

Codice:
public setta(int i){
	this.i = i;
}
cosi imposti il campo "i" con il valore "i" dato come argomento.


Questo è l'uso più frequente di this.


- un altro caso in cui this è usato e quando si deve invocare un metodo a cui passare l'oggetto corrente, e quidni lo si invoca come:

metodo(this);




Infine, tu stesso accennavi all'uso di this nei costruttori, in cui this viene invocato come se fosse un metodo. Una classe puo avere piu costruttori, l'importante è che i costruttori si distinguano per la lista degli argomenti; quindi all'interno di un costruttore, come prima istruzione, puoi invocare un costruttore con this:

this(<lista argomenti>);

in questo modo eviti di dover riscrivere tutte le istruzioni che erano contenute nel costruttore che stai invocando.


Esempio:

Hai una classe

Codice:
class Saluto{
	String tipoDiSaluto;
	
	public Saluto(String tipoDiSaluto){
		this.tipoDiSaluto = tipoDiSaluto;
	}
	
	public saluta(){
		System.out.ptintln(tipoDiSaluto);
	}
}
Questa classe riceve come argomento del costruttore una stringa che rappresenta un saluto; il metodo saluta() non fa altro che stampare questa stringa; cosi il seguente codice:

Saluto s = new Saluto("Ciao");
s.saluta();

farà stampare la stringa:

"Ciao"


Ora aggiungiamo un altro campo di tipo stringa che rappresenta il destinatario del saluto:

Codice:
class Saluto{
	String tipoDiSaluto;
	String destinatario;
	
	public Saluto(String tipoDiSaluto){
		this.tipoDiSaluto = tipoDiSaluto;
	}
	
	public Saluto(String tipoDiSaluto, String destinatario){
		this.tipoDiSaluto = tipoDiSaluto;
		this.destinatario = destinatario;
	}
	
	public saluta(){
		System.out.ptintln(tipoDiSaluto + "" + destinario);
	}
}
oltre al campo destinatario è stato aggiunto un nuovo costruttore per settare anche il destinatario; inoltre il metodo saluta() stampa il tipo di saluto più uno spazio più il destinatario; il seguente codice:


Saluto s = new Saluto("Ciao", "Gokan");
s.saluta();

farà satmpare la stringa:

"Ciao Gokan"


Ora, un modo alternativo di scrivere il secondo costruttore è questo:

Codice:
	public Saluto(String tipoDiSaluto, String destinatario){
		this(tipoDiSaluto);
		this.destinatario = destinatario;
	}
come vedi l'istruzione

this.tipoDiSaluto = tipoDiSaluto;

è stato sostituito da this(tipoDiSaluto); this(tipoDiSaluto) significa:

"Invoca il costruttore di questa calsse che ha un argomento di tipo stringa passandogli l'argoemento tipoDiSaluto".


In questo caso invocare il costruttore con this() o settare direttametne il campo non fa differenza; immagina pero una classe che ha un costruttore costituito da 100 righe di codice e un secondo costruttore che deve fare tutte le 100 righe di codice più altre ancora: in questo caso anzicche riscrivere le 100 righe di codice ti limiti a richiamare il costruttore opportuno con this() e la lista di argomenti che distingue quel costruttore dagli altri.
__________________
Sun Certified Java Programmer
EUCIP Core Level Certified

European Certification of Informatics Professionals

Ultima modifica di anx721 : 05-11-2004 alle 20:57.
anx721 è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2004, 08:37   #5
gokan
Senior Member
 
L'Avatar di gokan
 
Iscritto dal: Apr 2002
Città: Palermo
Messaggi: 4913
Perfetto
Adesso è tutto mooooolto più chiaro
Ho trovato particolarmente utile la parte in cui mi spieghi l'effettivo utilizzo di questa parola chiave. Sebbene avessi intuito il suo uso non capivo bene quando era facolatativo usarla e quando diventa obbligatoria. Posso dire quindi che, in linea teorica si potrebbe anche non usare (nel primo caso, dando all'argomento del metodo/costruttore un nome diverso dal campo della classe), ma che risulta tanto utile nell'uso con i costruttori, evitando tanta riscrittura di codice ridondante!!!!

Tante grazie
__________________
Sun Certified Java Programmer - Sun Certified Web Component Developer - Sun Certified Business Component Developer
gokan è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2004, 09:45   #6
gokan
Senior Member
 
L'Avatar di gokan
 
Iscritto dal: Apr 2002
Città: Palermo
Messaggi: 4913
Scrivo l'esempio successivo di uso di this:

Codice:
public class Flower {
  int petalCount = 0;
  String s = new String("null");
  
  Flower(int petals) {
    petalCount = petals;
    System.out.println(
      "Constructor w/ int arg only, petalCount= "
      + petalCount);
  }
  Flower(String ss) {
    System.out.println(
      "Constructor w/ String arg only, s=" + ss);
    s = ss;
  }
  Flower(String s, int petals) {
    this(petals);
//!    this(s); // Can't call two!
    this.s = s; // Another use of "this"
    System.out.println("String & int args");
  }
  Flower() {                                     //<-- chiamato per primo nel main
    this("hi", 47);
    System.out.println("default constructor (no args)");
  }
  void print() {
//! this(11); // Not inside non-constructor!
    System.out.println(
      "petalCount = " + petalCount + " s = "+ s);
  }
  public static void main(String[] args) {
    Flower x = new Flower();
    x.print();

   /* OUTPUT
      "Constructor w/ int arg only, petalCount= 47",
      "String & int args",
      "default constructor (no args)",
      "petalCount = 47 s = hi"
      */
    }
  }
Vediamo se interpreto bene
1) Nel main, con la creazione dell'oggetto
Flower x = new Flower();
parte il costruttore senza argomenti in input

2)il costruttore Flower() chiama il costrutttore con due argomenti
("hi", 47)

3)il costruttore con due argomenti chiama quello con un solo
argomento intero this(petals)

4) a questo punto il costrut Flower(int petals) stampa
Constructor w/ int arg only, petalCount= 47

Adesso è come se si ritornasse all'indietro, quindi

5)Si ritorna al costr Flower(String s, int petals), il quale mette s nella
this.s (che è il campo della classe, che era s="NULL") e stampa
String & int args

6) adesso si ritorna a Flower(), il quale stampa
default constructor (no args)

7)infine l'invocazione di x.print fa stampare
petalCount = 47 s = hi

Diciamo che seguendo il codice dovrebbe andare così

Se invece il codice era:
Codice:
public class Flower {
  int petalCount = 0;
  String s = new String("null");
  
  Flower(int petals) {
    petalCount = petals;
    System.out.println(
      "Constructor w/ int arg only, petalCount= "
      + petalCount);
  }
  Flower(String ss) {
    System.out.println(
      "Constructor w/ String arg only, s=" + ss);
    s = ss;
  }
  Flower(String s, int petals) {
    this(petals);
//!    this(s); // Can't call two!
    this.s = s; // Another use of "this"
    System.out.println("String & int args");
  }
  Flower() {                                     //<-- chiamato per primo nel main
    this("hi", 47);
    System.out.println("default constructor (no args)");
  }
  void print() {
//! this(11); // Not inside non-constructor!
    System.out.println(
      "petalCount = " + petalCount + " s = "+ s);
  }
  public static void main(String[] args) {
    Flower x = new Flower("azz",99);
    x.print();
   /* OUTPUT
      "Constructor w/ int arg only, petalCount= 99",
      "String & int args",
      "petalCount = 99 s = azz"
      */
    }
  }
Poichè viene chiamato
Flower x = new Flower("azz",99);

questa volta inizia il costruttore Flower(String s, int petals) e quindi l'ordine in cui vengono chiamati i rimanenti costruttori cambia, tanto è vero che il costrutt Flower() non viene mai chiamato, per cui
default constructor (no args) non viene mai stampato.

Ok, adesso ho capito
__________________
Sun Certified Java Programmer - Sun Certified Web Component Developer - Sun Certified Business Component Developer
gokan è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile iPhone 17 Pro: più di uno smartphone. &Eg...
Intel Panther Lake: i processori per i notebook del 2026 Intel Panther Lake: i processori per i notebook ...
Intel Xeon 6+: è tempo di Clearwater Forest Intel Xeon 6+: è tempo di Clearwater Fore...
4K a 160Hz o Full HD a 320Hz? Titan Army P2712V, a un prezzo molto basso 4K a 160Hz o Full HD a 320Hz? Titan Army P2712V,...
Recensione Google Pixel Watch 4: basta sollevarlo e si ha Gemini sempre al polso Recensione Google Pixel Watch 4: basta sollevarl...
Samsung è sempre più prota...
ChatGPT ha pregiudizi politici? Ecco cos...
Un solo iPhone rubato ha portato alla sc...
Xiaomi 17 Ultra sta arrivando: ecco come...
Il Motorola Edge 70 non ha più se...
Alcuni Galaxy S26 utilizzeranno il chip ...
Amazon, ecco i super sconti del weekend:...
Scovare un bug di sicurezza sui disposit...
Offerta Amazon su NordVPN: proteggi 10 d...
ECOVACS DEEBOT X8 PRO OMNI in offerta su...
Scope elettriche Tineco in offerta su Am...
Offerta Amazon sui robot EUREKA J15 Ultr...
Chrome disattiverà automaticament...
Tornano tutti e 4 i colori disponibili p...
Super sconto su iPhone 16: Amazon abbass...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 18:03.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v