
En Java, la discusión sobre Paso por Referencia o Paso por Valor puede resultar confusa al principio. Simplificando, Java siempre utiliza Paso por Valor, pero la clave está en entender qué es lo que realmente se está pasando por valor.
¿Qué significa Paso por Valor?
Paso por Valor significa que cuando pasas una variable a un método, el método recibe una copia del valor de esa variable. Modificar esa copia dentro del método no afecta a la variable original fuera del método.
Tipos Primitivos vs. Objetos
Aquí es donde la cosa se pone interesante. Java tiene dos tipos principales de variables: tipos primitivos (como int, boolean, double) y objetos (instancias de clases, como String, ArrayList o cualquier clase que hayas creado).
Must Read
Tipos Primitivos: Paso por Valor Directo
Con los tipos primitivos, el Paso por Valor funciona como se espera. Considera este ejemplo:
void modificarNumero(int numero) {
numero = numero + 10;
System.out.println("Dentro del método: " + numero); // Imprime un valor modificado
}
public static void main(String[] args) {
int miNumero = 5;
modificarNumero(miNumero);
System.out.println("Fuera del método: " + miNumero); // Imprime 5 (sin modificar)
}
Observa que miNumero no cambia porque modificarNumero recibe una copia de su valor.

Objetos: Paso por Valor de la Referencia
Con los objetos, el Paso por Valor implica pasar una copia de la referencia al objeto. La referencia es como una "flecha" que apunta a la ubicación del objeto en la memoria. Aunque el método recibe una copia de la "flecha", ambas "flechas" apuntan al mismo objeto.
Esto significa que si modificas el estado del objeto (sus atributos) dentro del método, esos cambios se reflejarán fuera del método, porque ambos estás operando sobre el mismo objeto. Pero, si dentro del método asignas una nueva instancia a la variable referencia, esto solo afecta la copia, no la referencia original.

class Persona {
String nombre;
public Persona(String nombre) { this.nombre = nombre; }
}
void modificarPersona(Persona persona) {
persona.nombre = "Nuevo Nombre";
System.out.println("Dentro del método: " + persona.nombre); // Imprime "Nuevo Nombre"
}
public static void main(String[] args) {
Persona miPersona = new Persona("Nombre Original");
modificarPersona(miPersona);
System.out.println("Fuera del método: " + miPersona.nombre); // Imprime "Nuevo Nombre"
}
En este caso, el nombre de la persona se modifica porque el método modificarPersona accede y modifica el objeto al que ambas referencias apuntan. Sin embargo, si dentro de la función `modificarPersona` hiciéramos `persona = new Persona("Otro Nombre");`, la variable `miPersona` en el `main` NO se vería afectada.
En resumen
Java siempre usa Paso por Valor. Para tipos primitivos, pasa una copia del valor. Para objetos, pasa una copia de la referencia (la "flecha" que apunta al objeto). Por eso, modificar el estado de un objeto dentro de un método puede afectar al objeto fuera del método.