Vai al contenuto

Java/Concetti fondamentali

Wikibooks, manuali e libri di testo liberi.

Java

Linguaggio Java
Linguaggio Java

categoria · sviluppo · modifica
Come posso contribuire?

→ Vai su Wikiversity

Java:  Guida alla programmazioneJava/Introduzione - Specifica di linguaggio - Libreria standardJava/Comunicazione seriale

Tipi di datoJava/Tipi di datoEspressioniJava/OperatoriVariabiliJava/Variabili localiIstruzioniJava/IstruzioniStrutture di controlloJava/Strutture di controlloPackageJava/Package
Classi e oggettiJava/Classi e oggettiOggettiJava/OggettiMetodiJava/MetodiMetodi (cont.)Java/Metodi/2ArrayJava/Array
Modificatori di accessoJava/Modificatori di accessoEreditarietàJava/Ereditarietà
Gestione delle eccezioniJava/Gestione delle eccezioniGenericsJava/Generics
Thread e parallelismoJava/MultithreadingInterblocco ricontrollatoJava/Interblocco ricontrollato
Alcune differenze con il CJava/Concetti fondamentaliLessicoJava/LessicoGrammaticaJava/Grammatica

Passaggio per valore o per riferimento

[modifica | modifica sorgente]
Nota: Questa sezione è destinata a coloro che provengono da altri linguaggi di programmazione, come il C.
Q: In Java, gli oggetti vengono passati ai metodi per valore o per riferimento? E i valori dei tipi base?
A:
  1. In Java, il passaggio degli argomenti avviene sempre per valore.
  2. Tuttavia, in Java gli oggetti non vengono mai passati come argomento; invece, vengono sempre passati i loro reference.

Quindi, non ha senso chiedere come vengano passati gli oggetti, perché gli oggetti non vengono mai passati.


Esempio. Data la classe InteroMutabile così definita:

final class InteroMutabile {
    
    private int _valore;
    
    public InteroMutabile(int valore) { _valore = valore; }
    
    public int getValue() { return _valore; }
    public void setValue(int valore) { _valore = valore; }
    
    private boolean _marcato = false;
    public void marcatura() { _marcato = true; }
    public boolean marcato() { return _marcato; }
    
}

questo codice

class A {
    
    private static void incrementa(InteroMutabile v) {
        v.marcatura();
        v = new InteroMutabile( v.getValue() + 1 );
    }
    
    private static void incrementa(int v) {
        v = v + 1;
    }
    
    public static void main(String[] args) {
        int numero = 0;
        InteroMutabile obj = new InteroMutabile(0);
        
        incrementa(numero);
        incrementa(obj);
        
        System.out.println(numero);
        System.out.println(obj.getValue());
        System.out.println(obj.marcato());
    }
}

stampa a video il seguente output:
0
0
true

perché

  • ciascuno dei due metodi incrementa() riceve sempre una copia del valore passato (che sia un valore di tipo int o un reference ad un oggetto), quindi l'assegnazione v = ... opera sempre su una variabile locale e non ha effetto sul metodo chiamante main();
  • tuttavia, nel caso di incrementa(InteroMutabile), le due copie del reference (quella che è nella variabile obj del main() e quella che è inizialmente nella variabile v di incrementa()) "puntano" allo stesso oggetto. Di conseguenza, il metodo marcatura() invocato da incrementa() tramite il reference che è nella variabile v opera sullo (e, quindi, modifica lo) stesso oggetto "puntato" dal reference contenuto nella variabile obj del metodo main(). Dopo l'assegnazione v = new InteroMutabile( v.getValue() + 1 ); la variabile locale v contiene un reference diverso, che punta ad un oggetto diverso, quindi System.out.println(obj.getValue()) stampa a video il valore del primo oggetto interoMutabile, che è ancora 0.