Java é uma linguagem de "passagem por valor". Isso significa que é feita uma cópia da variável e o método recebe essa cópia. As atribuições feitas no método não afetam o chamador. Vamos ver um exemplo:
2: public static void main(String[] args) {
3: int num = 4;
4: newNumber(5);
5: System.out.println(num); // 4
6: }
7: public static void newNumber(int num) {
8: num = 8;
9: }
Na linha 3, num é atribuído o valor de 4. Na linha 4, chamamos um método. Na linha 8, o parâmetro num é definido no método como 8. Embora esse parâmetro tenha o mesmo nome que o variável na linha 3, isso é uma coincidência. O nome pode ser qualquer coisa. O exame geralmente use o mesmo nome para tentar confundi-lo. A variável na linha 3 nunca muda porque não há atribuições feitas a ele.
Agora que você viu primitivas, vamos tentar um exemplo com um tipo de referência. O que você faz acha que é produzido pelo seguinte código?
public static void main(String[] args) {
String name = "Webby";
speak(name);
System.out.println(name);
}
public static void speak(String name) {
name = "Sparky";
}
A resposta correta é Webby . Assim como no exemplo primitivo, a atribuição de variável é apenas para o parâmetro method e não afeta o chamador.
Observe como continuamos falando sobre atribuições de variáveis. Isso ocorre porque podemos chamar métodos nos parâmetros. Como exemplo, temos um código que chama um método no StringBuilder transmitido para o método:
public static void main(String[] args) {
StringBuilder name = new StringBuilder();
speak(name);
System.out.println(name); // Webby
}
public static void speak(StringBuilder s) {
s.append("Webby");
}
Nesse caso, a saída é Webby porque o método simplesmente chama um método no parâmetro. Não reatribui o nome a um objeto diferente. Na Figura 4.4, você pode ver como a passagem por valor ainda é usada. s é uma cópia do nome da variável . Ambos apontam para o mesmo StringBuilder , o que significa que as alterações feitas no StringBuilder estão disponíveis para ambas as referências.
Idiomas diferentes tratam parâmetros de maneiras diferentes. A passagem por valor é usada por muitos idiomas, incluindo Java. Neste exemplo, o método de troca não altera a origem valores finais. É apenas altera um e b dentro do método.
public static void main(String[] args) {
int original1 = 1;
int original2 = 2;
swap(original1, original2);
System.out.println(original1); // 1
System.out.println(original2); // 2
}
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
A outra abordagem é a passagem por referência. É usado por padrão em alguns idiomas, como Perl. Nós não vamos mostrar o código Perl aqui porque você está estudando para o Java exame e não queremos confundi-lo. O exemplo a seguir está em um idioma inventado que mostra passagem por referência:
original1 = 1;
original2 = 2;
swapByReference(original1, original2);
print(original1); // 2 (not in Java)
print(original2); // 1 (not in Java)
swapByReference(a, b) {
temp = a;
a = b;
b = temp;
}
Veja a diferença? Em nossa linguagem inventada, o chamador é afetado pela atribuição de variáveis procedimentos realizados no método.
Para revisar, o Java usa a passagem por valor para inserir dados em um método. Atribuindo uma nova primitiva ou a referência a um parâmetro não altera o chamador. Chamando métodos em uma referência a um objeto afeta o chamador.
Recuperar dados de um método é mais fácil. É feita uma cópia da primitiva ou de referência e retornou do método Na maioria das vezes, esse valor retornado é usado. Por exemplo, pode ser armazenado em uma variável. Se o valor retornado não for usado, o resultado será ignorado. Observe isso no exame. Valores retornados ignorados são complicados.
Vamos tentar um exemplo. Preste atenção aos tipos de devolução.
1: public class ReturningValues {
2: public static void main(String[] args) {
3: int number = 1; // 1
4: String letters = "abc"; // abc
5: number(number); // 1
6: letters = letters(letters); // abcd
7: System.out.println(number + letters); // 1abcd
8: }
9: public static int number(int number) {
10: number++;
11: return number;
12: }
13: public static String letters(String letters) {
14: letters += "d";
15: return letters;
16: }
17: }
Essa é uma tarefa complicada, porque há muito para acompanhar. Quando você vê essas perguntas no exame, anote os valores de cada variável. As linhas 3 e 4 são atribuições diretas compromissos. A linha 5 chama um método. A linha 10 incrementa o parâmetro do método para 2, mas deixa o variável numérica no método main () como 1. Enquanto a linha 11 retorna o valor, o chamador ignora isto. A chamada de método na linha 6 não ignora o resultado, então as letras se tornam "abcd" . Lembrar isso está acontecendo devido ao valor retornado e não ao parâmetro method