“嗨,阿米戈!我希望你喜歡使用自己的方法解決任務,並希望你意識到創建方法是多麼方便。現在讓我們來談談最有趣的話題。”

“你激起了我的興趣,迭戈……一個新話題?”

“每個主題對你來說都是新的,我的小機器人!這個也不例外。雖然它又是關於方法的。你可能已經從方法中註意到我們可以將參數傳遞給方法。一旦我們進入方法 System.out.println()內部,我們將它們稱為參數。”

“參數就是我們寫在括號裡面的?”

“是的,完全正確。而且,事實上,參數極大地增強了我們從創建和使用方法中獲得的好處。”

“我明白你說的關於使用它們的意思,事實證明我已經做到了。我們如何聲明一個帶參數的方法?”

“其實很簡單:

public static void name(parameters)
{
  method body
}

“其中name是方法的唯一名稱,method body代表組成該方法的命令。而是parameters方法參數的佔位符,以逗號分隔。”

“嗯……我想我明白了……或者不明白……”

“讓我給你一些關於這個模板的更多細節,這樣你就可以確定你已經理解了:

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

這裡有些例子:

代碼 解釋
public static void print(String str)
{
}
print方法使用參數聲明:
String str
public static void print(String str, int count)
{
}
print方法使用兩個參數聲明:
String str
int count
public static void write(int x, int y)
{
}
write方法使用兩個參數聲明:
int x
int y

“啊……現在清楚了。如果我們不想讓方法有參數,那麼我們就把括號留空。”

“完全正確。基本上,參數是方法中的特殊變量。在它們的幫助下,您可以在調用方法時將各種值傳遞給方法。如果不需要傳遞值,則將括號留空。

“例如,讓我們編寫一個方法,將給定的文本行顯示給定的次數。關於如何做到這一點有什麼想法嗎?”

“嗯……看來我很清楚如何編寫代碼在屏幕上多次顯示一個字符串……”

“如何指定要顯示的字符串?如何指定顯示的行數?你能猜到嗎?”

“事情開始變得清晰起來……可能是藉助於方法參數?”

“完全正確。文本行的字符串參數和顯示行數的數字參數。執行此操作的代碼如下所示:

代碼 解釋
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);
   }
}

我們printLines使用以下參數聲明該方法:
String textint count

該方法顯示 Stringtext count



我們printLines使用各種參數調用該方法

“每次調用方法時,都會為其參數分配傳遞的值,然後我們才開始執行方法內部的命令。

參數

“我要你特別注意調用帶有參數的方法。傳遞給方法的值通常在傳遞給方法時稱為參數。

讓我們再看看我們的例子:

代碼 解釋
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);
   }
}

我們printLines使用以下參數聲明該方法:
String text,int count

該方法顯示 Stringtext count


我們printLines使用以下參數調用該方法:
text = "Hi"; count = 10;
text = "Bye"; count = 20;

“當printLines第一次調用該方法時,它的參數被分配了以下值:

String text = "Hi", int count = 10.

“當printLines第二次調用該方法時,它的參數被分配了不同的值:

String text = "Bye", int count = 20.

“參數不多於也不少於變量,在調用方法時會為其分配特定值。值"Hi", "Bye", 10, 和20本身稱為參數。”

“我會盡量記住區別,不要混淆這些概念。”

調用方法時變量名衝突

“當你調用一個方法時,你可以使用變量作為參數。

“嗯,有道理!”

“這是有道理的,但它可能會產生一些困難。讓我們再次回到我們的示例,但這一次我們將參數移動到單獨的變量中:

代碼 解釋
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";
     String n = 10;
     printLines(str, n);
   }
}

我們printLines使用以下參數聲明該方法:
String text,int count

該方法顯示 Stringtext count



我們printLines使用以下參數調用該方法:
text = str;
count = n;

“嗯……我看不出有什麼困難。我們有一個變量。它的值是在方法調用時str賦給參數的。我們有一個變量。它的值是在方法調用時賦給參數的。” “到目前為止,一切都很清楚。”textncount

“很好,很好。現在讓我們重命名方法中的變量main

代碼 解釋
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";
     String count = 10;
     printLines(text, count);
   }
}

我們printLines使用以下參數聲明該方法:
String text,int count

該方法顯示 Stringtext count



我們printLines使用以下參數調用該方法:
text = text;
count = count;

“注意兩點

第一:我們在不同的方法中有同名的變量。這些是不同的變量(我們故意用不同的顏色來描繪它們)。一切都與前面的示例相同,其中方法中的變量main被命名為strn

第二:調用該方法時不會發生任何神奇的事情。參數只是簡單地分配參數值。不管它們是數字、字符串、變量還是表達式。

“我們在主方法中重命名變量後,什麼都沒有改變。它們之前是不同方法中的不同變量,所以它們仍然存在。這兩個text變量之間沒有神奇的聯繫。”

“現在我明白了。”

傳遞對方法的引用

“我希望你已經吸收了我告訴你的關於將參數傳遞給方法的所有內容。我這麼說是因為我們現在要更深入地探討這個話題。仔細聽。”

“您已經知道,Java 中的某些變量存儲的不是值本身,而是一個引用,即值所在的內存塊的地址。這就是字符串變量和數組變量的工作方式。

“當開發人員將另一個數組變量分配給一個數組變量時,會發生什麼?”

“然後他們指向同一個地址嗎?”

“正確。這兩個變量開始引用內存中的相同空間:

“如果這些變量之一是方法參數,會發生什麼?

代碼 解釋
class Solution
{
   public static void sum(int[] data)
   {
     int total = 0;
     for (int i = 0; i < data.length; i++)
       total = total + data[i];
     System.out.println(total);
   }
   
   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     sum(months);
   }
}


sum方法計算傳入數組中數字的總和並將其顯示在屏幕上

“發生了完全相同的事情:data參數將包含對與變量相同的內存區域的引用months。調用該方法時,會發生簡單的賦值:。data = months

“而且由於兩個變量都引用存儲整數的同一內存區域,因此該sum方法不僅可以從數組中讀取值,還可以更改它們!”

“我想我明白了,但我需要更多的例子!”

“好吧,例如,我們可以編寫自己的方法,用相同的值填充二維數組。它看起來可能是這樣的:

代碼 解釋
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);
   }
}


fill 方法遍歷傳遞的二維數組中的每個單元格並分配value給它們。






我們創建一個二維數組。
我們用數字填充整個數組8

同名方法

“現在讓我們再次回到方法名稱上。”

“我無法想像關於名字還能說些什麼!”

“嗯,Java 語言標準要求同一類中的所有方法都具有唯一的名稱。

“所以,不可能在同一個類中聲明兩個同名方法?”

“現在——注意!一個類中的方法確實可以有相同的名稱!但在這種情況下,它們必須有不同的參數。換句話說,比較方法的相同性,不僅要考慮名稱,還要考慮參數的類型!請注意,我專門說的是類型。不考慮參數的名稱。示例:

代碼 解釋
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
這三種方法是不同的方法。它們可以在同一個類中聲明。
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
這五種方法中的每一種都被認為是不同的。它們可以在同一個類中聲明。
void sum(int x, int y) {
}
void sum(int data, int value) {
}
“這兩種方法被認為是相同的,這意味著它們不能在同一個類中聲明。”

“我完全糊塗了!為什麼我們需要所有這些?為什麼有些方法被認為是相同的,而另一些是不同的?為什麼在確定方法的唯一性時不考慮參數名稱?為什麼唯一性在全部?”

“問題在於,當編譯器編譯程序時,它必須確切地知道您打算在任何給定位置調用哪個方法。

“例如,如果你寫,編譯器很聰明,很容易斷定你打算用參數調用這裡的方法。但是如果你寫,編譯器會看到對方法的調用帶有參數。它不知道程序員在聲明方法時給參數起什麼名字。”System.out.println("Hi")println()StringSystem.out.println(1.0)println()double

啊啊,好像開始通關了!

“當一個方法被調用時,編譯器確保參數的類型與參數的類型相匹配。它不會關注參數的名稱。在 Java 中,參數名稱不會幫助編譯器確定要調用哪個方法調用。程序員需要它們,而不是編譯器。

“我想這就是為什麼在確定方法的唯一性時不考慮它們的原因?”

“是的,完全正確。方法的名稱及其參數的類型稱為方法簽名。例如,sum (int, int)

“所以每個類都必須有具有唯一簽名的方法,而不是具有唯一名稱的方法。”

“幹得好,阿米戈!你完美地總結了這一課。如果還有什麼不明白的地方,不要驚慌。這個話題會在幾次任務後變得清晰。”