DOMANDA Dubbio java

Stato
Discussione chiusa ad ulteriori risposte.

Fab996

Utente Attivo
177
5
Se ho questo codice
Codice:
public static void main(String[] args) {
    Ciao a = new Ciao();
    a.prova();
}

public void prova() {
    risultato();
}
public int risultato() {
    this.test();
}

Il this nel metodo risultato è un riferimento alla variabile a? Dato che il this si riferisce all'istanza corrente, ed essendo un puntatore, il this è un puntatore che ha lo stesso indirizzo di memoria della variabile puntata da a, quindi punta a ciò che punta a?
 

icox

Utente Attivo
497
246
Il this e' un riferimento all'istanza corrente, richiamandolo puoi riferirti ad metodo od una variabile di classe.
Nel tuo caso quel this.test() cerchera' di chiamare il metodo test() della classe in cui e' inserito il metodo risultato().
Quel codice non e' completo, cosa cerchi di fare esattamente?
 
  • Mi piace
Reazioni: Fab996

Fab996

Utente Attivo
177
5
Il this e' un riferimento all'istanza corrente, richiamandolo puoi riferirti ad metodo od una variabile di classe.
Nel tuo caso quel this.test() cerchera' di chiamare il metodo test() della classe in cui e' inserito il metodo risultato().
Quel codice non e' completo, cosa cerchi di fare esattamente?
Sisi, il codice non è completo perchè mi interessava solo capire il funzionamento del this, quando viene chiamato il metodo prova, davanti risultato() è dato per scontato il this giusto? Poi nel metodo risultato, this.test() il this si riferisce all'oggetto a creato nel main, ossia il this punta a ciò che punta a ?
 

icox

Utente Attivo
497
246
Ni. Dipende dalla struttura e da quali classi stai usando.
Se quel codice e' tutto dentro una classe Ciao, allora scrivere risultato() o this.risultato() produce lo stesso effetto, cosi come il this.test() e' uguale a test(), ma sempre solo se sono tutti metodi della stessa classe Ciao.
Diverso se invece quel codice e' di un'altra classe, supponiamo tu l'abbia chiamata MiaClasse: l'oggetto Ciao che crei e' definito in un'altra classe (Ciao, appunto) e per riferirti ai metodi di Ciao dovrai usare la dot notation, quindi (Ciao) a.nomeMetodo(). Non usi il this perche' in questo caso esso fa riferimento alla classe dove compare, quindi MiaClasse, e this.test() chiamera' il metodo di test() di MiaClasse (non di Ciao, come volevi).
In altre parole usi il this soltanto quando vuoi riferirti ad una variabile di classe o ad un metodo appartenente alla classe stessa; puoi evitare di scrivere il this se il nome di queste variabili o metodi sono univoci.
 
  • Mi piace
Reazioni: Fab996

Fab996

Utente Attivo
177
5
Si scusa, intendevo che quel codice sia tutto all'interno della stessa classe, quindi in questo caso this.test() il this si riferisce all'oggetto a creato nel main, ossia il this punta a ciò che punta a ?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
La parola chiave this si riferisce all'istanza corrente, come hai detto giustamente anche tu. Nel caso del tuo codice, le chiamate ai metodi sortiscono infatti il medesimo risultato: invocare direttamente risultato() o invocare this.risultato(), sortirebbe lo stesso effetto (si tratta sempre del membro della classe che richiami sull'istanza corrente).

Si scusa, intendevo che quel codice sia tutto all'interno della stessa classe, quindi in questo caso this.test() il this si riferisce all'oggetto a creato nel main, ossia il this punta a ciò che punta a ?

Il this non è un puntatore, è una parola chiave. La doc ufficiale è piuttosto chiara in merito (click), chiarendo anche quando ha senso utilizzare questa keyword.
 
  • Mi piace
Reazioni: Mursey e Fab996

Fab996

Utente Attivo
177
5
La parola chiave this si riferisce all'istanza corrente, come hai detto giustamente anche tu. Nel caso del tuo codice, le chiamate ai metodi sortiscono infatti il medesimo risultato: invocare direttamente risultato() o invocare this.risultato(), sortirebbe lo stesso effetto (si tratta sempre del membro della classe che richiami sull'istanza corrente).



Il this non è un puntatore, è una parola chiave. La doc ufficiale è piuttosto chiara in merito (click), chiarendo anche quando ha senso utilizzare questa keyword.
Quindi this.test() nel metodo risultato, il this si riferisce ad a, dato che a è la mia istanza corrente giusto? Perché il this oltre ad una parola chiave non può essere visto come un puntatore, dato che comunque è un riferimento (quindi contiene un indirizzo di memoria) che punta all'istanza corrente ?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Nel caso di specie, dopo la chiamata, si. Ma se da un'altra parte del codice viene creato un oggetto tipo:

Codice:
Ciao esempio = new Ciao();
esempio.prova();

L'oggetto corrente sarà differente, in quanto sei nel contesto di un altro oggetto.

Tecnicamente è una parola chiave, così come ad esempio new (che restituisce un riferimento alla memoria allocata). Internamente non so in che modo venga esattamente gestito però. ;)
In Java non valgono comunque le stesse considerazioni che varrebbero in C/C++, dove hai direttamente dei puntatori (dove gli indirizzi sono indirizzi virtuali); in Java utilizzi dei riferimenti, che non è corretto vedere esattamente come dei puntatori in senso stretto.
 
  • Mi piace
Reazioni: Fab996

Fab996

Utente Attivo
177
5
Va bene, ti ringrazio :)

Scusa posso anche chiederti l'utilizzo del this in costruttori sovraccarichi?:)
 
Ultima modifica da un moderatore:
  • Mi piace
Reazioni: DispatchCode

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Va bene, ti ringrazio :)

Scusa posso anche chiederti l'utilizzo del this in costruttori sovraccarichi?:)

In quel caso viene chiamato il costruttore della stessa classe che ha gli stessi parametri.
Esempio:

Java:
class A {
    private int n, m;   

    A(int n) {
      this.n = n;
    }

   A(int n, int m)
      this(n);
      this.m = m;
  }
}

Creando un oggetto come:

Codice:
A esempio = new A(10,100);

Viene richiamato il secondo costruttore, con i due parametri. Quel costruttore a sua volta invoca il costruttore con un parametro.
E' molto comodo in quanto ti consente di scrivere le cose una volta sola; se non ci fosse, il secondo costruttore con due parametri andrebbe riscritto così:

Java:
A(int n, int m) {
    this.n = n;
    this.m = m;
}

ripetendo quindi il lavoro che verrebbe già svolto dal primo costruttore. :)
 
  • Mi piace
Reazioni: Fab996

Fab996

Utente Attivo
177
5
Ma this(n) nel secondo costruttore, n si riferisce alla variabile d'istanza n o al parametro n che passi al costruttore?
Inoltre questo esempio più complesso come funziona?
Codice:
public class Ciao {

    private String n;
    private String m;
    private String a;

    public Ciao(String a) {
        this(null, null, a);
    }

    public Ciao(String n, String m) {
        this(n, m, null);
    }

    public Ciao(String n, String m, String a) {
        this.n = n;
        this.m = m;
        this.a = a;
    }
}
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Ma this(n) nel secondo costruttore, n si riferisce alla variabile d'istanza n o al parametro n che passi al costruttore?

Uno degli utilizzi del this è proprio quello di poter fare riferimento alla variabile d'istanza quando si hanno due variabili con lo stesso nome. Se ci pensi, è in effetti ciò che fai quando scrivi:
Java:
this.n = n;

stai dicendo che la variabile d'istanza n è uguale alla variabile n (il parametro).
Quindi nel caso da te citato la variabile utilizzata è quella del parametro. Ovviamente è così perchè ci sono due variabili con lo stesso nome. Se avessi::
Java:
A(int a) {
  this(n);
}

quella n si riferisce alla n della classe, la variabile d'istanza. Chiaramente in una situazione reale non si verifica, considerando che n non avrebbe alcun valore (di solito le inizializzazioni vengono fatte nel costruttore).

Inoltre questo esempio più complesso come funziona?
Codice:
public class Ciao {

    private String n;
    private String m;
    private String a;

    public Ciao(String a) {
        this(null, null, a);
    }

    public Ciao(String n, String m) {
        this(n, m, null);
    }

    public Ciao(String n, String m, String a) {
        this.n = n;
        this.m = m;
        this.a = a;
    }
}

Funziona esattamente come l'altro.
Se invochi il costruttore con un solo parametro, a sua volta lui invoca quello con 3 parametri inizializzando n ed m a null e la variabile a al valore del parametro a.
Se invochi quello con due stesso discorso, ma avrai n ed m inizializzate con a a null.

E' bene anche ricordare che le variabili membro non inizializzate esplicitamente hanno valori di default.
 
  • Mi piace
Reazioni: Fab996

Fab996

Utente Attivo
177
5
Grazie mille, poi se posso volevo chiederti una cosa che non è molto inerente a questo contesto. Volevo chiederti a livello di portabilità è più portabile un linguaggio interpretato o compilato? È vero che se in un calcolatore non c'è l'interprete non posso eseguire il programma scritto con un linguaggio interpretato, però se nel calcolatore non c'è il compilatore non posso neanche eseguire il programma scritto con un linguaggio compilato, quindi mi chiedevo quale fosse il linguaggio più portabile, che non dipenda dal tipo di macchina che utilizzo.
 
  • Mi piace
Reazioni: DispatchCode

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Grazie mille, poi se posso volevo chiederti una cosa che non è molto inerente a questo contesto. Volevo chiederti a livello di portabilità è più portabile un linguaggio interpretato o compilato? È vero che se in un calcolatore non c'è l'interprete non posso eseguire il programma scritto con un linguaggio interpretato, però se nel calcolatore non c'è il compilatore non posso neanche eseguire il programma scritto con un linguaggio compilato, quindi mi chiedevo quale fosse il linguaggio più portabile, che non dipenda dal tipo di macchina che utilizzo.

In effetti è un pò OT; un topic sull'argomento potrebbe anche risultare interessante, se si va anche ad approfondire. Valuta se aprirlo. ;)

Comunque per risponderti. In tal senso la portabilità non è un problema. Se il programma è interpretato serve appunto solo un interprete per poterlo eseguire. Se il linguaggio è compilato ha come target una precisa architettura: se compili per x64 non avrai tra i target x86. Se compili per ARM non funzionerà su x86/x64; se compili però per x86 funzionerà anche su x64.
In generale nel caso dei linguaggi compilati l'unico ostacolo - al di là dell'architettura stessa - è lo strato software che sta al di sopra, che ti costringe a ricompilare (mi riferisco al sistema operativo). Anche in questo caso però dovresti solo compilare due volte, ad esempio una per una distro Linux ed una per Windows. In questo senso il codice che scrivi è comunque portabile, in quanto devi solo compilare. L'ostacolo è dettato dalle librerie utilizzate nello sviluppo: se scrivo qualcosa usando ad esempio l'header windows.h, questo programma non girerà su Linux, e dovrò inevitabilmente riscriverne delle parti.

A titolo di completezza aggiungo solo che quando ci sono funzioni "non portabili", con target un preciso OS (o anche un preciso compilatore), si può sfruttare il pre-processore così da compilare solo ciò che effettivamente è utile. In questo modo scrivi il codice una volta sola. Chiaramente se ci sono intere porzioni di codice da riscrivere e questo implicherebbe una riscrittura completa... non avrebbe molto senso.
 
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili