Designing Methods

Every Java program we’ve seen has had a main() method. You can write
other methods too. For example, you can write a basic method to take a nap, as shown in
Figure 5.1.

This is called a method declaration, which specifies all the information needed to call the
method. There are many parts, and we cover each one in more detail. Two of the parts—
the method name and parameter list are called the method signature. The method signature
provides instructions for how callers can reference this method. The method signature does
not include the return type and access modifiers, which control where the method can be
referenced.
Below is a brief reference to the elements of a method declaration.

ElementValue in nap() exampleRequired?
Access modifierpublicno
Optional specifierfinalno
Return typevoidyes
Method namenapyes
Parameter list(int minutes)Yes, but can be empty
parentheses
Method signaturenap(int minutes)yes
Exception listthrows InterruptedExceptionno
Method body{
// take a nap
}
Yes, except for abstract
methods
Parts of a method declaration

To call this method, just use the method signature and provide an int value in parentheses: nap(10);
Let’s take a look at each of these parts of a basic method.

Access Modifiers

An access modifier determines what classes a method can be accessed from. Think of it like a security guard. Some classes are good friends, some are distant relatives, and some are complete strangers. Access modifiers help to enforce when these components are allowed to talk to each other. Java offers four choices of access modifier:

private: The private modifier means the method can be called only from within the same class.
Package Access: With package access, the method can be called only from a class in
the same package. This one is tricky because there is no keyword. You simply omit the
access modifier. Package access is sometimes referred to as package-private or default
access (even within this book!).

protected: The protected modifier means the method can be called only from a class in the same package or a subclass.
public: The public modifier means the method can be called from anywhere.

We explore the impact of the various access modifiers.
We’ll see practice examples as we go through each of the method elements. Make sure you understand why each of these is a valid or invalid method declaration. Pay attention to the access modifiers as you figure out what is wrong with the ones that don’t compile when inserted into a class:

public class Car {
 public void tyre1() {}
 default void tyre2() {} // DOES NOT COMPILE
 void public tyre3() {} // DOES NOT COMPILE
 void tyre4() {}
}

The tyre1() method is a valid declaration with public access. The tyre4() method is a valid declaration with package access. The tyre2() method doesn’t compile because default is not a valid access modifier. There is a default keyword, which is used in switch statements and interfaces, but default is never used as an access modifier. The skip3() method doesn’t compile because the access modifier is specified after the return type.

Optional Specifier

There are a number of optional specifiers for methods, shown on the table below. Unlike with access modifiers, you can have multiple specifiers in the same method (although not all combinations are legal). When this happens, you can specify them in any order. And since these specifiers are optional, you are allowed to not have any of them at all. This means you can have zero or more specifiers in a method declaration.

ModifierDescription
staticIndicates the method is a member of the shared class
object
abstractUsed in an abstract class or interface when the method
body is excluded
finalSpecifies that the method may not be overridden in a sub-clas
defaultUsed in an interface to provide a default implementation
of a method for classes that implement the interface
synchronizedUsed with multithreaded code
nativeUsed when interacting with code written in another
language, such as C++
strictfpUsed for making floating-point calculations portable
Optional specifiers for methods

While access modifiers and optional specifiers can appear in any order, they must all
appear before the return type
. In practice, it is common to list the access modifier first. Some specifiers are not compatible with one another.
For example, you can’t declare a method (or class) both final and abstract.

Do you see why these compile or don’t compile?

public class Activity{
 public void walk1() {}
 public final void walk2() {}
 public static final void walk3() {}
 public final static void walk4() {}
 public modifier void walk5() {} // DOES NOT COMPILE
 public void final walk6() {} // DOES NOT COMPILE
 final public void walk7() {}
}

The walk1() method is a valid declaration with no optional specifier. This is okay, it is optional, after all. The walk2() method is a valid declaration, with final as the optional specifier. The walk3() and walk4() methods are valid declarations with both final and static as optional specifiers. The order of these two keywords doesn’t matter. The walk5() method doesn’t compile because modifier is not a valid optional specifier. The walk6() method doesn’t compile because the optional specifier is after the return type. The walk7() method does compile. Java allows the optional specifiers to appear before the access modifier.

Return Type

The next item in a method declaration is the return type. It must appear after any access modifiers or optional specifiers and before the method name. The return type might be an actual Java type such as String or int. If there is no return type, the void keyword is used. This special return type comes from the English language: void means without contents.

When checking return types, you also have to look inside the method body. Methods with a return type other than void are required to have a return statement inside the method body. That return statement must include the primitive or object to be returned. Methods that have a return type of void are permitted to have a return statement with no value returned or omit the return statement entirely. Think of a return statement in a void method as the method saying, “I’m done!, I have completed your computations” and quitting early, such as the following

public void eat(int bites) {
 if(bites <= 0) {
 // Exit early, nothing to do!
 return;
 }
 System.out.print("Dog is eating" + bites+ " bites");
}

Can you explain why these methods compile or don’t?

public class Tree {
 public String int tree6() { } // DOES NOT COMPILE
 public void tree1() {}
 public String tree4() {} // DOES NOT COMPILE
 public void tree2() { return; }
 public String tree3() { return ""; }
 public tree5() {} // DOES NOT COMPILE
 String tree7(int a) { // DOES NOT COMPILE
  if (1 < 2) return "bush";
 }
}

Since the return type of the tree1() method is void, the return statement is optional. The tree2() method shows the optional return statement that correctly doesn’t return anything. The tree3() method is a valid declaration with a String return type and a return statement that returns a String. The tree4() method doesn’t compile because the return statement is missing. The tree5() method doesn’t compile because the return type is missing. The tree6() method doesn’t compile because it attempts to use two return types (String and int). You get only one return type.

The tree7() method is a little tricky. There is a return statement, but it doesn’t always get run. Even though 1 is always less than 2, the compiler won’t fully evaluate the if statement and requires a return statement if this condition is false. What about this modified version?

String tree9(int x) {
 if (1 < 2) return "branch";
 return "true"; // COMPILER WARNING
 }

The code compiles, although the compiler will produce a warning about unreachable code (or dead code). This means the compiler was smart enough to realize you wrote code that cannot possibly be reached.
When returning a value, it needs to be assignable to the return type. Whats wrong with the following pieces of code?

public class Measurement {
 int getWeight1() {
 int temp = 9;
 return temp;
 }
 int getWeight2() {
 int temp = 9L; // DOES NOT COMPILE
 return temp;
 }
 int getWeight3() {
 long temp = 9L;
 return temp; // DOES NOT COMPILE
 }
}

The getWeight2() method doesn’t compile because you can’t assign a long to an int. The method getWeight3() method doesn’t compile because you can’t return a long value as an int.

Method Name

Method names follow the same rules with variable names. To review, an identifier may only contain letters, numbers, currency symbols, or _. Also, the first character is not allowed to be a number, and reserved words are not allowed. The single underscore character is not allowed.
By convention, methods begin with a lowercase letter, but they are not required to. We are now jumping right into practicing with some examples:

public class Ceremony {
 public void activity1() {}
 public void 2activity() {} // DOES NOT COMPILE
 public activity3 void() {} // DOES NOT COMPILE
 public void Activity_$() {}
 public _() {} // DOES NOT COMPILE
 public void() {} // DOES NOT COMPILE
}

The activity1() method is a valid declaration with a traditional name. The 2activity() method doesn’t compile because identifiers are not allowed to begin with numbers. The activity3() method doesn’t compile because the method name is before the return type. The Activity_$() method is a valid declaration. While it certainly isn’t good practice to start a method name with a capital letter and end with punctuation, it is legal. The _ method is not allowed since it consists of a single underscore. The final line of code doesn’t compile because the method name is missing

Parameter List

A method doesn’t have to contain any parameters. This means you can just have an empty pair of parentheses after the method name, as follows:

public class Town {
 void location() {}
}

If you have multiple parameters, you separate them with a comma. There are a couple more rules for the parameter list. For now, we can practice looking at method declaration with “regular” parameters:

public class Ceremony {
 public void activity1() {}
 public void activity2 {} // DOES NOT COMPILE
 public void activity3(int a) {}
 public void activity4(int a; int b) {} // DOES NOT COMPILE
 public void activity5(int a, int b) {}
}

The activity1() method is a valid declaration without any parameters. The activity2() method does not compile because it is missing the parentheses around the parameter list. The activity3() method is a valid declaration with one parameter. The activity4() method doesn’t compile because the parameters are separated by a semicolon rather than a comma. Semicolons are for separating statements, not for parameter lists. The activity5() method is a valid declaration with two parameters.

Method Signature

A method signature is composed of the method name and parameter list, and it is what Java uses to uniquely determine exactly which method you are attempting to call. Once it determines which method you are trying to call, it then determines if the call is allowed. For example, attempting to access a private method outside the class or assigning the return value of a void method to an int variable results in compiler errors. Neither of these compiler errors is related to the method signature, though.
It’s important to note that the names of the parameters in the method signature are not used as part of a method signature. The parameter list is about the types of parameters and their order. For example, the following two methods have the exact same signature:

public class Ernest{
 public void goToChurch(String name, int waitTime) {}
 public void goToChurch(String location, int waitPeriod) {} // DOES NOT COMPILE
}

Despite having different parameter names, these two methods have the same signature and cannot be declared within the same class. Changing the order of parameter types does allow the method to compile, though:

public class Ernest{
 public void goToChurch(String name, int waitTime) {}
 public void goToChurch(int waitPeriod, String location) {} // DOES NOT COMPILE
}

Exception List

In Java, code can indicate that something went wrong by throwing an exception. In this article, you just need to know that it is optional and where in the method declaration it goes if present, there is another article for exceptions. For example, InterruptedException is a type of Exception. You can list as many types of exceptions as you want in this clause, separated by commas. For example:

public class PartyRule {
 public void firstExceptions() {}
 public void secondException() throws IllegalArgumentException {}
 public void thirdExceptions() throws
  IllegalArgumentException, InterruptedException {}
}

While the list of exceptions is optional, it may be required by the compiler, depending on what appears inside the method body. You learn more about this on exceptions article, as well as how methods calling them may be required to handle these exception declarations.

Method Body

The final part of a method declaration is the method body. A method body is simply a code block. It has braces that contain zero or more Java statements.

public class House {
 public void foor1() {}
 public void floor2() // DOES NOT COMPILE
 public void floor3(int f) { int name = 5; }
}

On the above code snippet, the floor1() method is a valid declaration with an empty method body. The floor2() method doesn’t compile because it is missing the braces around the empty method body. Methods are required to have a body unless they are declared abstract, we will cover it on a separate article. The floor3() method is a valid declaration with one statement in the method body.

// this is the end of this article, congratulations, you have covered the basics of methods (functions)

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights