“嗨,阿米戈!我希望你喜欢使用自己的方法解决任务,并希望你意识到创建方法是多么方便。现在让我们来谈谈最有趣的话题。”

“你激起了我的兴趣,迭戈……一个新话题?”

“每个主题对你来说都是新的,我的小机器人!这个也不例外。虽然它又是关于方法的。你可能已经从方法中注意到我们可以将参数传递给方法。一旦我们进入方法 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 text,int 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)

“所以每个类都必须有具有唯一签名的方法,而不是具有唯一名称的方法。”

“干得好,阿米戈!你完美地总结了这一课。如果还有什么不清楚的地方,不要惊慌。这个话题会在完成几个任务后变得清晰。”