Writing a Method

Now that we have practiced declaring a method, we are ready to fill in the code for methods. This code will look very similar to things we have been writing inside our main method (after all, main is also a method).

Void methods

We will first look at how to write the code for a void method (a method that does not return a value). These methods are slightly easier to implement than methods that return values.

Recall the method declaration for printing all the values in an integer array:

//This method prints every value in the nums array
public static void printArray(int[] nums) 
{

}

Now, we want to write code inside the brackets ({ }) of the method that will print all values in the nums array. This works exactly like it would if we were writing it in the main method – we just treat nums like we would any other variable. Here is the complete method:

//This method prints every value in the nums array
public static void printArray(int[] nums) 
{
    for (int i = 0; i < nums.length; i++) 
    {
        System.out.println(nums[i]);
    }
}

For another example, suppose we want to write a method that asks the user to input a certain number of integers, and then prints the sum of those numbers. This method needs to take the number of elements we want as an int parameter. It does not need to return anything because it is printing its result. Here is the complete method:

//This method asks the user for n numbers,
//and prints the sum of those numbers
public static void sumN(int n) 
{
    int sum = 0;
    Scanner s = new Scanner(System.in);

    for (int i = 0; i < n; i++) {
        System.out.print("Enter an integer: ");
        int val = s.nextInt();
        sum += val;
    }
    System.out.printf("The sum is: %d%n", sum);
}

Methods that return a value

Methods that return a value look fairly similar to void methods. The only difference is that all paths through a method that returns a value must end with the statement:

return expression;

where expression is either the name of a variable, some expression (a math operation, for example), or a constant value (like 4, true, or “hello”. Furthermore, expression should have the same data type as the return type for the method.

Recall the method declaration for computing the area of a rectangle:

// This method returns the area of the rectangle with
// length length and width width
public static double getArea(double length, double width) 
{

}

The formula for the area of a rectangle is the length times the width, so the completed method looks like this:

// This method returns the area of the rectangle with
// length length and width width
public static double getArea(double length, double width) 
{
    return length*width;
}

Notice that length*width is an expression whose data type evaluates to a double – the same type as the return type.

Next, recall the method declaration for counting the occurrences of a character in a string:

//This method returns the number of times letter appears in str
public static int countLetter(String str, char letter) 
{

}

To implement this method, we will have to loop through all the characters in str, and add one to a count variable every time a character matches letter. After we have finished looping through the string, we will return our count (which should have an int data type). Here is the implementation:

//This method returns the number of times letter appears in str
public static int countLetter(String str, char letter) 
{
    int count = 0;
    for (int i = 0; i < str.length(); i++) 
    {
        if (str.charAt(i) == letter) count++;
    }
    return count;
}

Finally, suppose we want to write a method that determines whether or not a particular letter is a character in a string. This method will again need to take the string and the character as parameters. Since it is computing whether or not something is true, its return type should be boolean. Here is the complete method:

//This method returns true if letter is in str, and false otherwise
public static boolean containsLetter(String str, char letter) 
{
    boolean foundIt = false;
    for (int i = 0; i < str.length(); i++) 
    {
        if (str.charAt(i) == letter) foundIt = true;
    }

    return foundIt;
}

This method is not as efficient as it could be, though. Suppose the first character in str matches letter – do we really need to look through the rest of the string? Here is an optimized version of the same method:

//This method returns true if letter is in str, and false otherwise
public static boolean containsLetter(String str, char letter) 
{
    for (int i = 0; i < str.length(); i++) 
    {
        //we've found letter -- no need to keep looking
        if (str.charAt(i) == letter) return true
    }

    //we must not have found letter, or we would have already returned
    return false;
}

Notice that in this version, there is a return statement in the middle of the method. That’s OK – it just means that if we do find a matching character, we immediately leave the method and return true without checking any other characters. If we do happen to make it out of the loop, we must not have found a match (otherwise we would have already returned true). So at this point, we can return false.

Rules for returning values

There are several rules for how to return values in non-void methods:

  • Every possible path through the method must end in a return statement
  • Consequently, a path cannot have any other code after its return statement

Let’s look at a couple of methods and determine whether or not they follow these rules:

//Incorrect: no return statement if num1 != num2
//This method returns whether num1 equals num2
public static boolean equal(int num1, int num2) 
{
    if (num1 == num2) return true;
}

The above method is not correct. If num1 does not equal num2, then no value will be returned. There must be a return statement for every possible scenario.

//Incorrect: print statement will never be reached
//This method returns whether num1 equals num2
public static boolean equal(int num1, int num2) {
    if (num1 == num2) return true;
    else {
        return false;
        System.out.println("Not equal");
    }
}

The above method is not correct. If num1 does not equal num2, we will return false. A return statement forces us to leave the method, so the print statement will never be executed. This method will give you a compiler error because it has unreachable code.

//Correct
//This method returns whether num1 equals num2
public static boolean equal(int num1, int num2) 
{
    if (num1 == num2) return true;
    else return true;
}

The above method is correct. If num1 equals num2, we return true. If num1 does not equal num2, we return false. Those are the only possible scenarios, and each of them has a return statement. We also don’t try to do anything else after returning a value.