位置:首页 > Java技术 > Java基础教程 > Java方法

Java方法

Java方法是组合在一起来执行操作语句的集合。当调用System.out.println方法,例如,该系统实际上是为了在控制台上显示的消息执行多条语句。

现在,您将学习如何创建自己的方法有或没有返回值,调用带或不带参数,使用相同的名称重载方法的方法,并运用抽象的方法在程序设计中。

创建方法:

在一般情况下,方法的语法如下:

modifier returnValueType methodName(list of parameters) {
  // Method body;
}

方法定义包括方法头和方法体。下面是一个方法的所有部分:

  • 修饰符: 修饰符是可选的,告诉编译器如何调用该方法。这定义了该方法的访问类型。

  • 返回类型: 方法可以返回一个值。returnValueType的值是方法返回的数据类型。有些方法没有返回值执行所需的操作。在这种情况下,returnValueType是关键字void.

  • 方法名称: 这是方法的实际名称。方法名和参数列表一起构成了方法签名.

  • 参数: 参数像一个占位符. 当调用一个方法,传递一个值给参数. 这个值被称为实际参数或参数. 参数列表是指类型,顺序和方法的参数的个数. 参数是可选的,也就是说,一个方法可以包含任何参数.

  • 方法体: 方法体包含定义哪些方法语句的集合.

Java Methods

注: 在某些其它语言中,方法被称为过程和函数. 非void返回值类型的方法被调用的函数; 有一个void返回值类型的方法被调用的程序.

例子:

这里是上面定义的方法的源代码,调用 max(). 这个方法有两个参数num1和num2,并返回两者之间的最大:

/** Return the max between two numbers */
public static int max(int num1, int num2) {
   int result;
   if (num1 > num2)
      result = num1;
   else
      result = num2;

   return result; 
}

调用方法:

在创建一个方法,是做什么的定义。若要使用方法,必须调用它。有两种方法来调用一个方法,该选择是基于该方法是否返回一个值或没有。

当程序调用一个方法时,程序控制权转移到被调用的方法。一个名为方法将控制返回给调用者时,其执行return语句或当达到其方法结束的右大括号。

如果该方法返回一个值,调用该方法通常被视为一个值。例如:

int larger = max(30, 40);

如果该方法返回void,则调用该方法必须是一个语句。例如,println方法返回void。下面的调用是一个语句:

System.out.println("Welcome to Java!");

例子:

以下是该示例演示如何定义一个方法,以及如何调用它:

public class TestMax {
   /** Main method */
   public static void main(String[] args) {
      int i = 5;
      int j = 2;
      int k = max(i, j);
      System.out.println("The maximum between " + i +
                    " and " + j + " is " + k);
   }

   /** Return the max between two numbers */
   public static int max(int num1, int num2) {
      int result;
      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result; 
   }
}

这将产生以下结果:

The maximum between 5 and 2 is 5

此程序包含 main()方法和max()方法。main方法是一样的,只不过它是由JVM调用的其他方法.

main方法的头始终是相同的,像在这个例子中,用修饰符public和static,返回值类型为void,方法名main和String[]类型的参数。String []表示该参数是一个String数组。

void 关键字:

本节介绍了如何声明和调用void方法。下面的例子给出了一个程序,它声明了一个名为printGrade方法并调用它打印的年级由一个给定的分数.

例子:

public class TestVoidMethod {

   public static void main(String[] args) {
      printGrade(78.5);
   }

   public static void printGrade(double score) {
      if (score >= 90.0) {
         System.out.println('A');
      }
      else if (score >= 80.0) {
         System.out.println('B');
      }
      else if (score >= 70.0) {
         System.out.println('C');
      }
      else if (score >= 60.0) {
         System.out.println('D');
      }
      else {
         System.out.println('F');
      }
   }
}

这将产生以下结果:

C

在这里,printGrade方法是一个void方法。它不返回任何值。调用一个void方法必须是一个语句。因此,它被调用在第3行中的main方法的声明。此语句像分号结尾的Java语句。

通过值传递参数:

当调用一个方法时,需要提供的参数,它必须以相同的顺序被指定为他们在法规范的相应参数。这就是所谓的参数顺序关联。

例如,下面的方法打印n次消息:

public static void nPrintln(String message, int n) {
  for (int i = 0; i < n; i++)
    System.out.println(message);
}

在这里,可以使用nPrintln("Hello", 3) 打印“Hello”三次。nPrintln("Hello", 3)语句通过实际的字符串参数,“Hello”这个参数来消息,打印“Hello”三次。不过,声明nPrintln(3, "Hello") 是错误的。 

当使用一个参数调用一个方法时,参数的值传递给参数。这被称作通过按值传递。如果参数是一个变量,而不是一个文本值,该变量的值传递给参数。可变不受影响,而不管是由于该参数的方法内的变化。

为简单起见,Java程序员常说传递一个参数x到参数y,这实际上意味着通过x的值设置为y。

例子:

下面是一个程序,演示了按值传递的效果。该程序创建用于交换两个变量的方法。Swap方法是通过传递两个参数调用。该方法被调用后不会改变的参数值。

public class TestPassByValue {

   public static void main(String[] args) {
      int num1 = 1;
      int num2 = 2;

      System.out.println("Before swap method, num1 is " +
                          num1 + " and num2 is " + num2);

      // Invoke the swap method
      swap(num1, num2);
      System.out.println("After swap method, num1 is " +
                         num1 + " and num2 is " + num2);
   }
   /** Method to swap two variables */
   public static void swap(int n1, int n2) {
      System.out.println("	Inside the swap method");
      System.out.println("		Before swapping n1 is " + n1
                           + " n2 is " + n2);
      // Swap n1 with n2
      int temp = n1;
      n1 = n2;
      n2 = temp;

      System.out.println("		After swapping n1 is " + n1
                           + " n2 is " + n2);
   }
}

这将产生以下结果:

Before swap method, num1 is 1 and num2 is 2
        Inside the swap method
                Before swapping n1 is 1 n2 is 2
                After swapping n1 is 2 n2 is 1
After swap method, num1 is 1 and num2 is 2

重载方法:

前面使用 max方法仅适用于int数据类型。但是,如果需要找到其中两个浮点数的具有最大的值呢,怎么办?解决的办法是用相同名称但由不同的参数来建立另一种方法,如下面的代码:

public static double max(double num1, double num2) {
  if (num1 > num2)
    return num1;
  else
    return num2;
}

如果调用max为int参数,即整型参数将被调用的max方法,如果调用max传递double类型参数,即预计double参数将被调用max()方法。这被称为方法的重载,也就是说,两种方法具有相同名称但不同的参数列表在一个类中。

Java编译器决定哪些方法是根据方法的签名中使用。重载方法可以使程序更清晰,更具可读性。执行密切相关的工作方法应给予相同的名称.

重载的方法必须有不同的参数列表。不能重载根据不同的修饰方法或返回类型. 有时是由于类似的方法签名的方法的调用两个或多个可能的匹配,所以编译器无法确定最精确的匹配。这被称为不明确的调用.

变量的作用域:

一个变量的范围是其中变量可以被引用的程序的一部分。在一个方法中定义的变量称为局部变量。

局部变量的范围始于它的声明,并继续到包含该变量的块的结束。局部变量必须先声明它才能使用。

一个参数实际上是一个局部变量。方法参数的范围包括整个方法。

在一个初始动作部分的for循环头部声明的变量具有其在整个循环范围。但里面声明的for循环体内的变量具有其范围仅限于从声明的循环体,其中包含如下所示的变量块的结尾:

Java Variable Scope

可以在一个方法不同的非嵌套块相同的名字多次声明一个局部变量,但不能在嵌套块中声明一个局部变量两次。

使用命令行参数:

当运行它来传递信息到一个程序。这是通过命令行参数main()来完成。

命令行参数是直接跟随在命令行程序的名称在执行时的信息。要访问一个Java程序中的命令行参数是很容易的。它们被存储为字符串传递给main() 的String数组中。

例子:

下面的程序显示所有的命令行参数,它被调用:

public class CommandLine {

   public static void main(String args[]){ 
      for(int i=0; i<args.length; i++){
         System.out.println("args[" + i + "]: " +
                                           args[i]);
      }
   }
}

尝试执行该程序,如下所示:

java CommandLine this is a command line 200 -100

这将产生以下结果:

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

构造函数:

构造函数初始化创建时的对象。它具有相同的名称作为它的类,并在语法上类似的方法。然而,构造函数没有明确的返回类型。

通常情况下,使用一个构造函数由类定义的实例变量赋予初始值或执行,以创建一个完全成型的对象所需要的任何其他启动程序。

所有的类都有构造函数,不管有没有定义,Java会自动提供一个默认的构造函数来初始化所有成员变量为零。然而,一旦定义自己的构造函数,默认的构造函数不再使用。

例子:

下面是一个使用一个构造一个简单的例子:

// A simple constructor.
class MyClass {
   int x;
   
   // Following is the constructor
   MyClass() {
      x = 10;
   }
}

将调用构造函数来初始化对象,如下所示:

public class ConsDemo {

   public static void main(String args[]) {
      MyClass t1 = new MyClass();
      MyClass t2 = new MyClass();
      System.out.println(t1.x + " " + t2.x);
   }
}

大多数情况下,需要接受一个或多个参数的构造函数。参数被添加到一个构造函数,因为它们被添加到一个方法以同样的方式,构造函数的名称后到刚刚声明它们的括号内。

例子:

下面是一个使用一个构造一个简单的例子:

// A simple constructor.
class MyClass {
   int x;
   
   // Following is the constructor
   MyClass(int i ) {
      x = i;
   }
}

调用构造函数来初始化对象,如下所示:

public class ConsDemo {

   public static void main(String args[]) {
      MyClass t1 = new MyClass( 10 );
      MyClass t2 = new MyClass( 20 );
      System.out.println(t1.x + " " + t2.x);
   }
}

这将产生以下结果:

10 20

可变参数(VAR-参数):

JDK 1.5中,可以将可变数量的相同类型的参数传递到一个方法。该方法中的参数声明如下:

typeName... parameterName

在方法声明中,指定后跟省略号(...)只有一个可变长度参数可以在一个方法中指定的类型,这个参数必须是最后一个参数。任何常规参数必须在它前面。

例子:

public class VarargsDemo {

   public static void main(String args[]) {
      // Call method with variable args  
	  printMax(34, 3, 3, 2, 56.5);
      printMax(new double[]{1, 2, 3});
   }

   public static void printMax( double... numbers) {
   if (numbers.length == 0) {
      System.out.println("No argument passed");
      return;
   }

   double result = numbers[0];

   for (int i = 1; i <  numbers.length; i++)
      if (numbers[i] >  result)
      result = numbers[i];
      System.out.println("The max value is " + result);
   }
}

这将产生以下结果:

The max value is 56.5
The max value is 3.0

finalize( ) 方法:

这是可能的定义,将刚刚被垃圾收集器的对象的最终毁灭之前被调用的方法。调用方法finalize(),并且它可以被用来确保一个对象终止清理干净。

例如,可能使用的finalize(),以确保该对象拥有一个打开的文件关闭。

为了要终结器添加到类,只需要定义finalize()方法。 Java运行时调用该方法时,它是关于回收该类的一个对象。

finalize方法里面,将指定一个对象被销毁之前,必须执行这些操作。

finalize()方法的通用格式如下:

protected void finalize( )
{
   // finalization code here
}

在这里,关键字protected是一个规范,防止访问在finalize()其类外定义代码。

可以不知道什么时候或者即使finalize()执行。例如,如果垃圾收集发生在程序结束前,finalize()将不会执行。