Java possui dois tipos de dados,
Tipo primitivo:
Englobam os tipos numéricos (byte, short, int, long, char, float, double) e booleano (boolean). Uma variável de tipo primitivo recebe um valor primitivo, este valor é armazenado diretamente no espaço de memória alocado para a variável. Exemplo:
public static void main(String[] args) {A figura ao lado representa as duas áreas de memória alocadas para as variáveis a e b, cada uma mantendo o seu respectivo valor.
byte a = 10;
byte b = a;
}
Tipo referência:
englobam os tipos classes, interfaces e arrays. Salientando que uma String é uma classe. Uma variável do tipo referência recebe como valor uma referência para um objeto. Na área de memória da variável é armazenado um ponteiro para a área de memória que está o objeto. Objeto é uma instância de classe ou array. Exemplo:
public static void main(String[] args) {
Carro a = new Carro();
Carro b = a;
}
Figura apresenta a área de memória alocada para o objeto Carro e as duas áreas de memória alocadas para as variáveis a e b. Notem que as duas variáveis possuem áreas de memórias distintas, mas que referenciam o mesmo objeto.
Concluindo, passagem de parâmetro em Java é SEMPRE POR VALOR, isto é, ao passar uma variável como parâmetro de um método sempre será efetuada a cópia dos bits desta variável,
Variável primitiva:
public static void main(String[] args) {Notamos que o conteúdo da variável preco foi copiado para a variável parametro, portanto quando somamos 5 a variável parametro estamos alterando apenas o conteúdo desta variável, enquanto a variável numero permanece com o mesmo valor.
byte preco = 10;
System.out.println("Preço antes : " + preco);
// Saída "Preço antes : 10"
somaPreco(preco);
System.out.println("Preço depois: " + preco);
// Saída "Preço depois: 10"
}
private static void somaPreco(byte parametro) {
parametro += 5;
}
Variável referência:
public static void main(String[] args) {Aqui o conteúdo da variável carro é passado para a variável parametro, ou seja, uma cópia da referência para o objeto Carro, as duas variáveis apontam para o mesmo objeto. Quando alteramos o conteúdo da variável parametro para null, a variável carro permanece inalterada.
Carro carro = new Carro();
carro.preco = 10;
System.out.println("Preço antes : " + carro.preco);
// Saída "Preço antes : 10"
somaPreco(carro);
System.out.println("Preço depois: " + carro.preco);
// Saída "Preço depois: 10"
}
private static void somaPreco(Carro parametro) {
parametro = null;
}
private static class Carro {
byte preco;
}
Talvez a dúvida da galera tenha ocorrido pela maioria ser desenvolvedor C++, onde o tipo referência tem uma conotação um pouco diferente.
A regra de passagem por valor pode ser generalizada para qualquer atribuição, passagem de parâmetro ou retorno de método em Java, sempre é feita a cópia dos bits da variável, ou seja, SEMPRE POR VALOR.
Referência: Java Language Specification