1. Passando argumentos

E agora começa a diversão. Você provavelmente já sabe de métodos como esse System.out.println()que podemos passar argumentos para métodos. Uma vez dentro do método, nos referimos a eles como parâmetros. Na verdade, os parâmetros aumentam muito os benefícios que obtemos ao criar e usar métodos.

Como declaramos um método com parâmetros? Na verdade é bem simples:

public static void name(parameters)
{
  method body
}

Onde name é o nome exclusivo do método e method body representa os comandos que compõem o método. E parameters é um espaço reservado para os parâmetros do método, separados por vírgulas. Vamos descrever este modelo com mais detalhes:

public static void name(Type1 name1, Type2 name2, Type3 name3)
{
  method body
}

Exemplos:

Código Explicação
public static void print(String str)
{
}
O printmétodo é declarado com um parâmetro:
String str
public static void print(String str, int count)
{
}
O printmétodo é declarado com dois parâmetros:
String str
int count
public static void write(int x, int y)
{
}
O writemétodo é declarado com dois parâmetros:
int x
int y

Se não quisermos que o método tenha parâmetros, basta deixar os parênteses vazios.

Parâmetros são variáveis ​​especiais dentro de um método. Com a ajuda deles, você pode passar vários valores para o método quando ele é chamado.

Por exemplo, vamos escrever um método que exibe uma string de texto um determinado número de vezes.

Você já sabe escrever código para exibir uma string na tela várias vezes. Mas qual string você deve imprimir? E quantas vezes? É para isso que precisamos dos parâmetros.

O código que faz isso ficaria assim:

Código Explicação
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}


Declaramos o printLinesmétodo com os seguintes parâmetros:
String text, int count
O método exibe String text counttimes





Chamamos o printLinesmétodo com vários parâmetros

Cada vez que um método é chamado, seus parâmetros recebem os valores passados, e só então começamos a executar os comandos dentro do método.


2. Argumentos

Gostaria de chamar um pouco mais a atenção de vocês para a chamada de um método com parâmetros.

Os valores passados ​​para o método geralmente são chamados de argumentos quando são passados ​​para o método.

Vejamos outro exemplo:

Código Explicação
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}


Declaramos o printLinesmétodo com os seguintes parâmetros:
String text, int count
O método exibe String text counttimes




Chamamos o printLinesmétodo com os seguintes argumentos:
text = "Hi"; count = 10;
text = "Bye"; count = 20;

Quando o printLines método foi chamado pela primeira vez, seus parâmetros receberam os seguintes valores:
String text = "Hi", int count = 10.

Quando o printLinesmétodo foi chamado pela segunda vez, seus parâmetros receberam valores diferentes:
String text = "Bye", int count = 20.

Parâmetros são nem mais nem menos que variáveis ​​que recebem determinados valores quando um método é chamado. Os valores "Hi", "Bye", 10e 20são chamados de argumentos."


3. Nomes de variáveis ​​conflitantes ao chamar um método

Variáveis ​​podem ser usadas como argumentos de método. Isso é simples e compreensível, mas pode potencialmente produzir algumas dificuldades. Vamos voltar ao mesmo exemplo, mas desta vez vamos mover os argumentos para variáveis ​​separadas:

Código Explicação
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String str = "Hi";
     int n = 10;
     printLines(str, n);
   }
}


Declaramos o printLinesmétodo com os seguintes parâmetros:
String text, int count
O método exibe String text counttimes







Chamamos o printLinesmétodo com os seguintes argumentos:
text = str;
count = n;

Até aqui, tudo bem: temos uma strvariável. Seu valor é atribuído ao textparâmetro quando o método é chamado. Temos uma nvariável. Seu valor é atribuído ao countparâmetro quando o método é chamado." Até agora, tudo está claro.

Agora vamos renomear nossas variáveis ​​no mainmétodo:

Código Explicação
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String text = "Hi";
     int count = 10;
     printLines(text, count);
   }
}


Declaramos o printLinesmétodo com os seguintes parâmetros:
String text, int count
O método exibe String text counttimes







Chamamos o printLinesmétodo com os seguintes argumentos:
text = text;
count = count;

Preste atenção em duas coisas

Primeiro: temos variáveis ​​com o mesmo nome em métodos diferentes. Estas são variáveis ​​diferentes (nós as representamos deliberadamente usando cores diferentes). Tudo funciona igual ao exemplo anterior, onde as variáveis ​​do mainmétodo foram nomeadas stre n.

Segundo: Nada de mágico acontece quando o método é chamado. Os parâmetros são simplesmente atribuídos aos valores de argumento. Independentemente de serem números, strings, variáveis ​​ou expressões.

Após renomearmos as variáveis ​​no método main, nada mudou. Elas eram variáveis ​​diferentes em métodos diferentes anteriormente, e assim permanecem. Não há nenhuma conexão mágica entre as variáveis text ​​e text .



4. Passando referências a métodos

Espero que você tenha entendido tudo da lição anterior, porque agora vamos revisitar a passagem de argumentos para métodos, só que vamos nos aprofundar mais.

Como você já sabe, algumas variáveis ​​Java não armazenam os valores em si, mas sim uma referência, ou seja, o endereço do bloco de memória onde os valores estão localizados. É assim que funcionam as variáveis ​​string e variáveis ​​array.

Quando você atribui outra variável de array a uma variável de array, o que acontece? Isso mesmo. As duas variáveis ​​passam a se referir ao mesmo espaço na memória:

Passando referências a métodos

E o que acontece se uma dessas variáveis ​​for um parâmetro de método?

Código Explicação
class Solution
{
   public static void printArraySum(int[] data)
   {
     int sum = 0;
     for (int i = 0; i < data.length; i++)
       sum = sum + data[i];
     System.out.println(sum);
   }

   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     printArraySum(months);
   }
}


O printArraySummétodo calcula a soma dos números no array passado e exibe na tela

Acontece exatamente a mesma coisa: o data parâmetro conterá uma referência à mesma área de memória da monthsvariável. Quando o método é chamado, ocorre uma atribuição simples: .data = months

E como ambas as variáveis ​​se referem à mesma área de memória que armazena um inteiro, o printArraySum método pode não apenas ler valores do array, mas também alterá-los!

Por exemplo, podemos escrever nosso próprio método que preenche um array bidimensional com o mesmo valor. Pode ser assim:

Código Explicação
class Solution
{
   public static void fill(int[][] data, int value)
   {
     for (int i = 0; i < data.length; i++)
     {
       for (int j = 0; j < data[i].length; j++)
         data[i][j] = value;
     }
  }

   public static void main(String[] args)
   {
     int[][] months = {{31, 28}, {31, 30, 31}, {30, 31, 31}};
     fill (months, 8);
   }
}


O fill método itera sobre cada célula na matriz bidimensional passada e atribui valuea eles.








Criamos um array bidimensional.
Preenchemos todo o array com o número 8.


5. Métodos com o mesmo nome

Agora vamos retornar aos nomes dos métodos mais uma vez.

Os padrões Java exigem que todos os métodos da mesma classe tenham nomes exclusivos. Em outras palavras, é impossível declarar dois métodos com nomes idênticos na mesma classe.

Quando os métodos são comparados quanto à semelhança, não apenas os nomes são levados em consideração, mas também os tipos dos parâmetros ! Observe que os nomes dos parâmetros não são levados em consideração . Exemplos:

Código Explicação
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
Esses três métodos são métodos diferentes . Eles podem ser declarados na mesma classe.
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
Cada um desses cinco métodos é considerado diferente . Eles podem ser declarados na mesma classe.
void sum(int x, int y) {
}
void sum(int data, int value) {
}
Esses dois métodos são considerados iguais , o que significa que não podem ser declarados na mesma classe.

Por que alguns métodos são considerados iguais , enquanto outros são diferentes ? E por que os nomes dos parâmetros não são levados em consideração ao determinar a exclusividade de um método?

Por que a exclusividade é necessária? O problema é que, quando o compilador compila um programa, ele deve saber exatamente qual método você pretende chamar em determinado local.

Por exemplo, se você escrever , o compilador é inteligente e facilmente concluirá que você pretende chamar o método aqui com um parâmetro.System.out.println("Hi")println()String

Mas se você escrever , o compilador verá uma chamada para o método com um parâmetro.System.out.println(1.0)println()double

Quando um método é chamado, o compilador garante que os tipos dos argumentos correspondam aos tipos dos parâmetros. Ele não presta atenção ao nome dos argumentos. Em Java, os nomes dos parâmetros não ajudam o compilador a determinar qual método chamar. E é por isso que eles não são levados em consideração ao determinar a unicidade de um método.

O nome de um método e os tipos de seus parâmetros são chamados de assinatura de método . Por exemplo,sum(int, int)

Cada classe deve ter métodos com assinaturas exclusivas em vez de métodos com nomes exclusivos.