Java Tutorial, Part 3: (Static) Methods

I've been thinking about how to structure this tutorial a lot, and I decided to teach you all about methods before I get into object orientation, so you'll have to wait a little while longer before we get into the real nitty-gritty. To understand this one, you should've already read and understood tutorials 1 and 2. If you haven't, you can get to them by clicking the "Previous Post" button in the navigation bar.

So, here goes!

Methods

Methods are a way, in programming, to move certain code into a different location where it's more organized and, more importantly, where it can be called multiple times from multiple locations, possibly with different data. You'll see what exactly that means in a minute.

Let's create a simple method in our main class:

public class Main {
    public static void main(String[] args) {
        // I've omitted the code from the previous tutorials for readability
    }

    public static void printInfo() {
        System.out.println("This is some important information!");
    }
}

Let's take a look at the printInfo method I created. In this tutorial, we'll only be talking about public and static methods, so you'll just have to take that part for granted for now. Following that, you write void and then the name of your method (which can be anything you want), followed by parentheses () and then braces {}. Similarly to the if statement and the for loop, the method's content goes between those two curly braces, as I have done in this example with the print statement.

As you can see, all a method is is pretty much a collection of code. At this point, you might've already noticed that that is exactly what the main structure we've previously been writing all of our code into is: main is just another method.

To call a method, that is to have the code inside of it be executed, all you have to do is write the following:

public class Main {
    public static void main(String[] args) {
        // I've omitted the code from the previous tutorials for readability

        printInfo();
    }

    public static void printInfo() {
        System.out.println("This is some important information!");
    }
}

There you go.

Variables

It should be noted at this point that variables which are declared inside of a method, like the ones we've been using in the first two tutorials, are known as local variables. What this means is that they only exist inside of the method they are declared in. Check out this example:

// This method declares a variable i that is set to 0
public static void methodOne() {
    int i = 0;
}

// This method declares a *different* variable i that is set to 1
public static void methodTwo() {
    int i = 1;
}

// This method will cause an error if you paste it into your IDE:
// You cannot declare two variables with the same name in one method.
public static void erroringMethod() {
    int i = 0;
    int i = 1;
}

This same behavior also counts for if, for and any other curly braces {} that you see: They close off any variables which are created inside of them and make them available to only that location.

Parameters

Now you might be wondering what the point of methods is if all they do is execute a predefined list of code. Well… you can actually make a method accept a set of data that they can use to do their processing. The data given to a method is called parameters, and these parameters are simply variables that you declare between the method's parentheses () right after its name.

Let's take the following example:

public static void printInfo(String strg) {
    System.out.println("This is some important information about " + strg);
}

I modified the method by adding the parameter strg to it, which is of the type String. What this means is that now, when calling the method, it expects you to give it a string that it can use to do stuff with (in this case, print it out).

If you add that parameter to the code we previously wrote, you might notice that your IDE is now displaying an error to you. You can't just do this anymore:

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

As we just said, printInfo now wants us to give it a string whenever we call it. To give it that string, simply put it between the parentheses () of your method call like this:

String someString = "Some String";
printInfo(someString);

// or, optionally, the shorter form:
printInfo("Some String");

Running your code now should cause This is some important information about Some String to be displayed in your console.

In case you're thinking "I've seen that somewhere before", then you would be correct: This is exactly the same thing you do when you try to print something out to the console: You call the println method and give it the text you want to print out as the parameter.

The cool thing is that a method can also accept multiple parameters, so multiple bits of data can be passed into it when calling it. Let's look at this example:

public class Main {
    public static void main(String[] args) {
        printInfo("Some String", 5);
    }

    public static void printInfo(String strg, int amount) {
        for (int i = 0; i < amount; i = i + 1) {
            System.out.println("This is some important information about " + strg);
        }
    }
}

As you can see, the printInfo method now takes two parameters, separated by a comma ,. The code inside of the method should already be familiar to you: It's a simple for loop that prints the same message amount times.

So now, we have something that also demonstrates pretty well the versatility of methods: We can now call printInfo with any information that will be printed any amount of times:

printInfo("Some String", 5);
printInfo("Some other String", 10);

Returning

Another thing that methods can do that is really useful is the ability to return certain data. What this means is that they can, after their execution finishes, take the data they created or modified and give it back to the caller:

public class Main {
    public static void main(String[] args) {
        int tenSquared = square(10);
        System.out.println(tenSquared); // prints 100
        System.out.println(square(5)); // prints 25
    }

    public static int square(int i) {
        return i * i;
    }
}

As you can see, I created a method square that returns its parameter i, but squared. To make a method return a value, two things have to be done:

  • The method's return type has to be declared. For methods that don't return anything, the return type is void. For methods that return something, just replace void with the type of variable that it returns.
  • To actually return a specific value after it has been calculated, just type return, followed by the value and a semicolon ;.

Now, this method can be used as if it were just another number: We can set variables to it and print it out. But instead of it being just another number, it actually executes the code inside it every time.

Stopping execution

A thing that should be noted about returning is that any code that comes after a return statement will not be executed. In other words: After returning a value, a method will stop its execution, no matter what comes next.

public static int square(int i) {
    return i * i;
    System.out.println("This will never be called");
}

In this specific case, that isn't really useful - why write code that can never be executed? But take this other example:

public static boolean isIGreaterThanJ(int i, int j) {
    if (i > j) {
        return true;
    }

    System.out.println("i is NOT greater than j!");
    return false;
}    

In this example, the print statement will not be executed if i is greater than j despite the fact that it's not wrapped in an else, because the method gets returned out of before it can be called.

Requirements

If you create a method that has a return type other than void (which, again, means "this method doesn't return anything"), then every possible path that the execution can take inside the method needs to return something.

What this means is that you can't have something like this:

public static boolean isIGreaterThanJ(int i, int j) {
    if (i > j) {
        return true;
    }

    System.out.println("i is NOT greater than j!");
}

Because when i is not greater than j, the print statement will be executed but then, the method doesn't know what value to return, so this code will give out an error before it even tries to execute.

Conclusion

So yea, that's pretty much everything important there is to know about (static) methods. In one of the next tutorials, we'll finally get into actual object orientation and we'll soon be taking a look at non-static methods, which are even more useful than static methods.

As a little exercise, you might want to create some methods with different return types and different parameters and call them. Have some fun!

I hope you enjoyed reading, and of course: Happy coding!

10/11/2019Discuss this post