Thursday, 26 April 2018

Core Java: Method(Function)

At times, a certain portion of codes has to be used many times. Instead of re-writing the codes many times, it is better to put them into a "subroutine", and "call" this "subroutine" many time - for ease of maintenance and understanding. Subroutine is called method (in Java) or function (in C/C++).
 
The benefits of using methods are:
 
1.      Divide and conquer: construct the program from simple, small pieces or components. Modularize the program into self-contained tasks.
 
2.      Avoid repeating codes: It is easy to copy and paste, but hard to maintain and synchronize all the copies.
 
3.      Software Reuse: you can reuse the methods in other programs, by packaging them into library codes.

Using Methods
 
Two parties are involved in using a method: a caller, who calls or invokes the method, and the method called.
The process is:
 
  1. The caller invokes a method and passes arguments to the method.
  2. The method:
  1. receives the arguments passed by the caller,
  2. performs the programmed operations defined in the method's body, and
  3. returns a result back to the caller.
    3.The caller receives the result, and continue its operations.
 
Example: Suppose that we need to evaluate the area of a circle many times, it is better to write a method called getArea(), and re-use it when needed.
 
  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class EgMethodGetArea {
   // The entry main method
   public static void main(String[] args) {
      double r = 1.1, area, area2;
      // Call (Invoke) method getArea()
      area = getArea(r);
      System.out.println("area is " + area);
      // Call method getArea() again
      area2 = getArea(2.2);
      System.out.println("area 2 is " + area2);
      // Call method getArea() one more time
      System.out.println("area 3 is " + getArea(3.3));
   }

   // Method getArea() Eefinition.
   // Compute and return the area (in double) of circle given its radius (in double).
   public static double getArea(double radius) {
      return radius * radius * Math.PI;
   }
}
 
The expected outputs are:
area is 3.8013271108436504
area 2 is 15.205308443374602
area 3 is 34.21194399759284
 
In the above example, a reusable method called getArea() is defined, which receives an argument in double from the caller, performs the calculation, and return a double result to the caller. In the main(), we invoke getArea() methods thrice, each time with a different parameter.
Take note that there is a transfer of control from the caller to the method called, and from the method back to the caller, as illustrated.
 












 
Tracing Method Invocation
 
You can trace method operations under Eclipse/NetBeans:
·        Step Over: Treat the method call as one single step.
 
·        Step Into: Step into the method, so that you can trace the operations of the method.
 
·        Step Out: Complete the current method and return to the caller.
 
·        Set "Breakpoints" inside the method, and "resume" running to the first breakpoint.
 
 
Method Definition Syntax
 
The syntax for method definition is as follows:
public static returnValueType methodName ( arg-1-type arg-1, arg-2-type arg-2,... ) {
   body ;
}
Method Naming Convention
 
A method's name shall be a verb or verb phrase (action), comprising one or more words. The first word is in lowercase, while the rest are initial-capitalized (called camel-case). For example, getArea(), setRadius(), moveDown(), isPrime(), etc.
Another Example:
 
/** Example of Java Method definition and invocation */
public class EgMinMaxMethod {
   // The entry main() method
   public static void main(String[] args) {
      int a = 6, b = 9, max, min;
      max = max(a, b);  // invoke method max() with arguments
      min = min(a, b);  // invoke method min() with arguments
      System.out.println(max + "," + min);
  
      System.out.println(max(5, 8)); // invoke method max()
      System.out.println(min(5, 8)); // invoke method min()
   }

   // The max() method returns the maximum of two given numbers
   public static int max(int number1, int number2) {
      return (number1 > number2) ? number1 : number2;
   }

   // The min() method returns the minimum of two given numbers
   public static int min(int number1, int number2) {
      return (number1 < number2) ? number1 : number2;
   }
}
  
The "return" statement
 
Inside the method body, you could use a return statement to return a value (of the returnValueType declared in the method's signature) to return a value back to the caller. The syntax is:
return aReturnValue;   // of returnValueType declared in method's signature
return;                // return nothing (or void)
  
 
The "void" Return-Type
 
Suppose that you need a method to perform certain actions (e.g., printing) without a need to return a value to the caller, you can declare its return-value type as void. In the method's body, you could use a "return;" statement without a return value to return control to the caller. In this case, the return statement is optional. If there is no return statement, the entire body will be executed, and control returns to the caller at the end of the body.
Notice that main() is a method with a return-value type of void. main() is called by the Java runtime, perform the actions defined in the body, and return nothing back to the Java runtime.
  
 
Actual Parameters vs. Formal Parameters
 
Recall that a method receives arguments from its caller, performs the actions defined in the method's body, and return a value (or nothing) to the caller.
In the above example, the variable (double radius) declared in the signature of getArea(double radius) is known as formal parameter. Its scope is within the method's body. When the method is invoked by a caller, the caller must supply so-called actual parameters or arguments, whose value is then used for the actual computation. For example, when the method is invoked via "area1=getArea(radius1)", radius1 is the actual parameter, with a value of 1.1.
 
 Pass-by-Value for Primitive-Type Parameters
 
In Java, when an argument of primitive type is pass into a method, a copy is created and passed into the method. The invoked method works on the cloned copy, and cannot modify the original copy. This is known as pass-by-value.
For example,
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class PassingParameterTest {
   public static void main(String[] args) {
      int number = 8;                // primitive type
      System.out.println("In caller, before calling the method, number is: " + number);  // 8
      int result = increment(number); // invoke method
      System.out.println("In caller, after calling the method, number is: " + number);   // 8
      System.out.println("The result is " + result);  // 9
   }

   public static int increment(int number) {
      System.out.println("Inside method, before operation, number is " + number); // 8
      ++number;  // change the parameter
      System.out.println("Inside method, after operation, number is " + number);  // 9
      return number;
   }
}
  
Varargs - Method with Variable Number of Formal Arguments (JDK 1.5)
 
Before JDK 1.5, a method has to be declared with a fixed number of formal arguments. C-like printf(), which take a variable number of argument, cannot not be implemented. Although you can use an array for passing a variable number of arguments, it is not neat and requires some programming efforts.
JDK 1.5 introduces variable arguments (or varargs) and a new syntax "Type...". For example,
 
public PrintWriter printf(String format, Object... args)
public PrintWriter printf(Local l, String format, Object... args)
 
Varargs can be used only for the last argument. The three dots (...) indicate that the last argument may be passed as an array or as a sequence of comma-separated arguments. The compiler automatically packs the varargs into an array. You could then retrieve and process each of these arguments inside the method's body as an array. It is possible to pass varargs as an array, because Java maintains the length of the array in an associated variable length.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class VarargsTest {
   // A method which takes a variable number of arguments (varargs)
   public static void doSomething(String... strs) {
      System.out.print("Arguments are: ");
      for (String str : strs) {
         System.out.print(str + ", ");
      }
      System.out.println();
   }

   // A method which takes exactly two arguments
   public static void doSomething(String s1, String s2) {
      System.out.println("Overloaded version with 2 args: " + s1 + ", " + s2);
   }

   // Cannot overload with this method - crash with varargs version
   // public static void doSomething(String[] strs)

   // Test main() method
   // Can also use String... instead of String[]
   public static void main(String... args) {
      doSomething("Hello", "world", "again", "and", "again");
      doSomething("Hello", "world");

      String[] strs = {"apple", "orange"};
      doSomething(strs);  // invoke varargs version
   }
}
 
Notes:
·        If you define a method that takes a varargs String..., you cannot define an overloaded method that takes a String[].
 
·        "varargs" will be matched last among the overloaded methods. The varargsMethod(String, String), which is more specific, is matched before the varargsMethod(String...).
 
·        From JDK 1.5, you can also declare your main() method as:
public static void main(String... args) { .... }  // JDK 1.5 varargs
 

No comments:

Post a Comment

Please write your view and suggestion....