Home > Developing & using methods > Developing & using methods in Java

Developing & using methods in Java

 

Module 3: Developing & using methods

 

Objectives:

  • Describe the advantages of methods and define worker and calling methods.
  • Declare and invoke a method.
  • Compare object and static methods.
  • Use overloaded methods.

 

 

1. Describe the advantages of methods and define worker and calling methods:

Creating and invoking methods:

Let’s begin our discussion of methods by  looking into the syntax required to declare a method in a class.

 Creating and invoking methods 

 

[modifiers] -> The modifiers are optional keywords that modify the behavior of a method. Some of these modifiers are the keywords, public, private, protected and static. We will look into all of them in the coming posts.

return_type  -> First thing that all the methods should have is the return type. Every method can return utmost one value. If the method does not return anything, then the method must specify the keyword void. If it does return a value, the value can either be primitive or a object reference. For instance, if the method returns an integer, then the return type should be specified as int, if the method returns an object such as String, then the return value should be specified as String.

method_identifier -> This is the name that you assign to a method such as displayShirtInformation.

Then we have the paranthesis and inside of it we have arguments. The paranthesis are always required whether we have arguments or not.

[arguments] -> The arguments are optional. This will be a list of variables, whose values will be passed into the method as input. The method can then use those values to do something with them, such as print them to the console etc.

Then we have the left and right curly brace, enclosing the method_code_block. These are always required.

method_code_block -> These are lines of Java code, that you will want to be executed when the method is called.

 

Basic form of a method:

Let’s take a look at an example of method declaration. Here we have a class called Shirt inside of which we have a method called displayShirtInformation() that’s been declared. Notice the optional modifier public specified indicating that this method can be invoked from anywhere, the return type void specifying that the method doesn’t return anything, then the name of the method displayShirtInformation followed by a pair of paranthesis which is empty i.e., specifying that the method doesn’t take any arguments. Then we have the left curly brace which encloses the code block of Java code that we want to be executed whenever this method is called. And then we have a terminating right curly brace specifying the end of method body.

 

Basic form of a method

 

 

To the right, we have a class called ShirtTest. Inside of it we have a method called main method. Notice the optional modifier public specified indicating that this method can be invoked from anywhere. We also have static. You can have valid multiple combination of modifiers in the method declaration. We will cover it all in detail in the coming posts. Then we have the return type void indicating that this method doesn’t return anything. Then we have the method identifier as main. As we know from before, this is the entry point into a Java program.

Then we have the paranthesis enclosing one argument. We have an array of Strings called args that will be passed to this method. We will talk about arrays in posts to come. Then we have our left curly brace beginning our method body, then we have our lines of Java code that are to be executed whenever this method is called. And then we end the method body by closing the braces.

Notice that on line 9, the code is invoking displayShirtInformation() method in the Shirt class. So in this case the main method is called the calling method or the caller method whereas the displayShirtInformation() method is called as the worker method. When one method calls another, the calling method is called the caller method, and the called method is called the worker method.

Also, notice how we have called the displayShirtInformation() method. We have used the Shirt object reference called myShirt and the dot notation (.) and the name of the method. When one class wants to call a method in another class, it needs an object reference of that class to invoke a method in that class.

 

Guidelines for invoking methods:

Here’s something to keep in mind when using methods.

 

 Guidelines for invoking methods

 

 

Passing arguments and returning values:

Let’s see how to pass arguments from the caller method to the worker method and passing the return values from the worker method back to the caller method. As we can see from the figure below, we have 2 methods, method 1 and method 2. Suppose the method 1 is the caller method and the method 2 is the worker method.

 

 Passing arguments and returning values

 

 Let’s say in line 3 of caller method, it calls the worker method passing a value say v1 to it. The worker method will receive that value and then begins executing its lines of code. And let’s say in line 8 of the worker method, it issues a return statement returning a value v2 to the caller method. This return value is recieved by the caller method at the line where it invoked the worker method, thats at line 3, and then the execution resumes from the next line.

 

 

2. Declare and invoke a method:

Declaring methods with arguments:

Now we will see how to declare methods that accept arguments and how those arguments are passes to the methods and then how these methods return values. In the figure below, you can see that we have 2 methods, a caller and a worker method. foo() is our caller method, which calls the multiply(x,y) method passing in 2 arguments to be multiplied together. multiply() method is the worker method. It is the method which is declaring 2 arguments have to be passed to it. Let’s take a look at this first.

 

Declaring methods with arguments

 

You can see that we start of the multiply() method, specified with the modifier keyword public, and then the keyword void indicating that this method doesn’t return  a value. Then we have the name of the method which is multiply. And then in paranthesis we have the arguments that this method accepts. Notice that the arguments are declared just like variables are declared because arguments are only local variables to the method. These arguments will be passed with the values from the caller method and the variables here will be intialized to those values just like any other local variable.

Here we have 2 integer variables num1 and num2. These are our argument.s You can have as many arguments as you like. You just need to seperate them with a comma (,). Then down in the foo() method, we can see how to pass values to the multiply method. All we need to do to invoke a method is to specify the name of the method and in paranthesis, we list the different values that we want to be passed to the method. So, in this case we want to pass x and y values to the multiply method.

All arguments are passed by value. So the value in the x variable will be copied into the num1 variable and the value in the y variable will be copied into the num2 variable. All the local variables are allocated in the stack memory. Let’s see how the stack memory is utilized during the execution of the method. In the foo() method, when the variable x and y are declared and initialized, these variables are allocated in the stack memory. Then the multiply method is called, then the num1 and the num2 variables are also allocated in the stack memory. Then the multiply method begins to execute, and the result local variable is also allocated in the stack. The CPU will then multiply num1 and num2 and store that into the result variable.

Notice that we haven’t returned a value from the multiply method. So, when the multiply method exits, the result local variable is removed from the stack, and so will be num1 and num2. And the value that we calculated is now gone and lost. And then we return back to the foo method. And when the foo method exits, the x and y variable are removed from the stack. So you can see that whatever we did in the methods are lost as the local variables in the method were removed when the method completed its execution and we don’t have track of the values we need. So, we need to know how to return a value.

 

The main method:

Now that we have seen how do methods accept arguments, let’s revist the main method. The main method accepts 1 argument, which is an array of Strings. We will keep arrays for later but what we want to know here is how do we pass this array of Strings into the main method. Because unlike other methods which are called from your own code, the main method is called from JVM (Java Virtual Machine). So, to pass this array of Strings we do it from the command prompt.  

 The main method

 

So, when you type the java command in the console to begin the execution of a program, you can add on additional arguments that you want passed in as Strings. We can see in the command prompt, we can type java ShirtTest and then the optional Strings that we want passed in. In this case we are passing in 12.99 and the letter R. Even though 12.99 is a number, the JVM will treat it as a String, and pass it to the main method as a String. If you wish to treat it as a number in your program, you will need to convert it from String to a number later in your code. In this case, you will get an array of Strings passed into the main method, this array will have 2 Strings in it.

 

Declaring methods with return values:

Now let’s see how to return a value from the worker method back to the caller method. Here we have the example from before but we have modified it so that the multiply method will return the value that it calculates back to the foo method. So, let’s see how its done.

 

 Declaring methods with return values

 

 

As you can see in the multiply method, we have taken away the void keyword and replaced it with the int. This indicates that the multiply method will return an integer value. Remember, that a method can return utmost one value. And once we specify a return type, we must issue a return statement in the method which ends the method and this will be the last line in the method. The return statement has a return keyword followed by the value to be returned. In this case, the return statement is specifying to return the value in the result variable. This value will be returned to the calling method.

So, now lets turn our attention to the foo method and see how this method will receive the returned value. As you can see the foo method is almost the same as before but now we have an additional local variable called z of type integer. This z variable is getting initialized with a value returned from the multiply method. Initially when the foo methods begins its execution, x and y variable are intialized and allocated in the stack memory. And also the z variable is allocated on the stack but it has no initial value.  And then the multiply method is called and the variables num1 and num2 are allocated in stack as well.

The values of x and y are copied into num1 and num2 local variables respectively. Then once the execution of the multiply method begins, the result variable is also allocated in the stack, and the CPU multiplies num1 and num2 and the value is copied into the result variable. Then we have the return statement, which is returning the value from the result variable to the calling method foo, and this value is copied into the z variable.  This illustrates how the values are passed as arguments, and how the returned value is passed back to the calling method.

 

Advantages of method use:

Now that we have seen what methods are, how to create them, how to pass arguments to them, and return values from them, one might be wondering why do so much and not just right all the lines of code from top to bottom of it. There are many reasons for using methods and let’s take a look at some of them.

  • Methods make programs more readable and easier to maintain:  For example, it is much easier to figure out what a program is doing if the code is divided among several diffrent methods with names that match the behavior of the methods. For instance, displayShirtInformation() method is so readable, that we can know what this method will be doing than actually reading the lines of code that make this method.
  • Methods make development and maintainence quicker: For example, you can choose to create and test your program one method at a time to ensure that the program, as a whole, will work when finished. This makes division of work easy. For instance, developers can share a method to code and test its working independantly. Also if there is any problem in a method, its easier to fix the code as it can be recognized easily and also can have individual tests to a method. They are short, simple and easier to debug so you dont have to go through hundreds of lines of code.
  • Methods are central to reusable software: For example, the Java technology class libraries have many classes with methods that you can use over and over again in your programs. You will likely write a few methods that other programmers can use too. For instance, we have used the println method over and over again in many examples so far, if we had to just write the lines of code all the time, then it makes our program unnecessarily longer. So methods allow us to reuse code.
  • Methods allow seperate objects to communicate and distribute the work performed by the program: A method in one object can invoke a method in another object. The object can pass the method information and recieve a return value. For instance, we would like objects to perform functions that are relevant to them, such as a Shirt object having a displayShirtInformartion method.

 

 

 

3. Compare object and static methods:

Creating static methods and variables:

Here we will see about static attributes and static methods. The easiest way to understand the static functionality is to compare it with normal methods and variables (objects). Let’s look into an example.

 

Creating static methods and variables

 

Here we have a class called Alpha. It has an attribute x which is of type integer. These are our normal attributes. It also has another attribute variable y which is also of type integer but declared static by using the static modifier. The class also has 2 methods. One method namely beta() is similar to other methods we have discussed so far. The another method gamma() is declared static again by using the keyword static.

So, let’s see how this modifier will change the way the attributes and the methods behavior. As you can see from the figure, we have 2 Alpha objects. Each Alpha object has its own x variable. The x attribute is a normal instance attribute. That is every Alpha object get its own x variable. The same thing happens with the beta() method. Each Alpha object gets its own beta() method. In reality it doesnt work this way, but conceptually you can think of it this way, that every Alpha object has its own beta() method.

Now compare this to y variable and the gamma() method which have static modifiers. Since it has static modifier attatched to it, there is only 1 y variable shared among all Alpha objects. That is all Alpha objects have the reference to same y variable. If one object changes the y variable then all other objects see those changes. The same thing happens with the gamma() method. There is only 1 gamma method that is shared amongst all objects of the Alpha class.  

By adding the static modifier to either the variable or the method, we are declaring that there should be only one of those, that is shared amongs all objects of this class. The arrows that you see in the figure point out what methods can access what variables. For instance, the Alpha object to the left has its own x variable, and its own beta() method. This beta() method can access its own x variable, and also access the shared y variable and shared gamma() method. The Alpha object to the right, has its own x variable and beta() method, wherein the beta() method can access its own x variable, and also access  the shared y variable and shared gamma() method.

Here you have to notice that the shared gamma() method can only access the shared y variable. It can not access either of the x variables. The reason is, if in your gamma() method, if you refer to a x variable, the gamma method would not know which x variable you are referring to since there are 2 of them in this case and may be many in other cases. The same logic applies that a gamma() method can not be coded to access beta() method since there can be more than one beta() method and it would not be possible to know which beta() method to refer to.

To re-iterate, an instance method can access static / non -static variables / methods. A static method on the other hand can only access static variables.

 

Invoking static methods:

Now that we know what a static variable and a static method are, let’s see how we use them. Unlike a normal method or a normal attribute which requires an object reference to be able to access them, static variables and static methods do not. They are available immediately. To access them you use the class name which has this static variable / method. Let’s see how this is done.

 

  Invoking static methods

 

In the AlphTest class, we have a main method. This class i going to access the Alpha class from the previous section. As you can see in the main method, we are using the class name Alpha and the dot notation and then the y variable to access the y variable of the Alpha class and setting its value to 7. And on the next line we are calling the gamma() method of the Alpha class once again using the class name and the dot notation. Notice that we haven’t yet created an Alpha object yet the y attribute and the gamma() method are available immediately. This is one of the upsides to the use of static variables / methods i.e., you dont have to create an object to access them.

Compare this to the normal variable / method in the following lines. Notice how we have to first create the Alpha object so that we can access either y variable or beta() method. We are using the object reference a and the dot notation and the variable x to set its value to 5. We are also using the object reference to access the beta() method on the Alpha class. Note that you can also use the object reference, if you have one, to access the static variable / method, i.e., in our example using object reference a we can access either y or gamma() method (a.y or a.gamma()). But this is not the preferred method. It is always preferred that you use class name to access static variable / method.  The reason is, it makes it more readable for anyone to know that the y variable and the gamma() method are static. They dont have to look into a class to find that information out.

 

Static example:

Now lets take a look at a more realistic example of a static method / variable to see where you might use them. Here we have a method called convertShirtSize which takes a numerical size as argument such as 10, 12 0r 15 and convert it into a letter size. For instance, a size 12 will be converted into a medium. Now the questions you should be asking yourself to determine whether a variable / method should be static or not, is does the static method need to access any instance / attribute data? If it doesnt then it could be a good candidate to be a static method. Also do i really need a object to be able to call this method or could this function just stand on its own without an object?  

 

Static example

 

In this case its pretty clear that if we put this method inside a Shirt class, we really dont need individual Shirt object to be created to be able to call this method. This looks more like a utility method that we should be able to call anytime. So you can see that we have decided to declare this method as static. And down, you can see that we are calling this method using the class name and passing the size value as 16. This method can be called at anytime to convert a numerical size into a letter size. So you can see that this utility function really doesnt need a Shirt object to perform a conversion.

 

Static methods and variables in the Java API:

Let’s take a look at some of the static members (variables / methods) in the Java API. This will even give you a better of idea of why and when to use these. For instance, from the Math class, has nothing but static variables and static methods in it. One of the attributes is Math.PI, which represents the pi value of 3.14.etc. It also has a square root function, Math.sqrt(double) that takes a double and will return you a square root of the number passed. It also has a Math.random() method which will generate a random number.

 

 

 Static methods and variables in the Java API

 

Then from the System class. We have already been using System.out.println(). The out attribute in the System class is static attribute. It provides us an always available means to output the contents to the command prompt. The System class also has a method System.currentTimeMillis() which provides the current time in milli seconds. Again as its static, its always available for you to call. As you can see from these example API classes, many times the methods are declared static when they have to be available anytime to any class and without the need of an object and when they provide certain common or utility functionality that do not use any object references.

 

When to declare a static method or variable:

 Here are some tips to help you decide whether are not an attribute / method can be declared static or not.  

  • The method or object does not need to be tied to a specific object reference. This is like our convertShirtSize method which stood on its own. It did not need a Shirt object for it to be valid. So we made it static so that we could use it at anytime.
  • If accessing a variable or method before instantiating an object is important. For instance, we might want to call convertShirtSize method before creating a Shirt object. That’s when we would want this method to be static. Also like the Math.PI variable in the Math class, we want to use this variable whenever there is a calcuation that involves a pi. We don’ t have to create a Math object first.
  • If the method or a variable doesn’t logically belong to an object (functionally / behaviorally relate to an object such as displayShirtInformation method) and can stand on its own, then you might want to create a utility class for that method / variable just like the Math class is. This utility class just has logical methods grouped together that perform certain reusable functions such as Math.sqrt etc and don’t need a Math object to do those calculations. Hence they have been put in a class called Math as they all are mathematical calculations and are declared static so that they can be accessed without an object but just with the class name Math.

 

 

3. Use overloaded methods:

Now we are going to see about method overloading. In many languages, you can use a method / function / procedure once and thats it. But in Java and other object oriented languages, you may use a method name more than once as long as the signatures are different. We will see what a signature is in a while. In the figure, you can see that we have a class called Calculator with 3 methods declared, all of them are called sum. But they have different signatures. The first sum method takes 2 arguments both of which are integers. This is called its signature.

So, the signature is a method name + argument types and not the name of the argument or even the return type of a method that a method takes. So, the signature for the first method is (sum, int, int). The signature for the second method is sum, float, float and for the third is sum, int, float. So, we have 3 sum methods but they all have different signatures. For the signatures to be different, either the type of the arguments must be different or the number of arguments must be different. Here in this example we have different types of arguments. We can have another method with sum, int, int, int as it differs with number of arguments from the first method.

 

Use overloaded methods

 

This concept is called method overloading that is when you use a same method name in a class multiple times but you have different signatures for those methods. Let’s see how Java knows which method to call. To the right, we have a class called CalculatorTest which has a main method calling our different overloaded sum methods. The first call to the sum method is passing 2 and 3 as arguments. Notice the arguments being passed are integers, hence Java knows that it has to invoke sum, int, int for this method call. Its just matching up the signatures. Similarly the second call to the sum method is passing 15.9F and 12.8F as arguments, so Java knows that it has to invoke sum, float, float for this method call. Then in the third call, 2 and 12.8F are passed as arguments, so Java will invoke the sum, int, float method.

Then in the fourth call, we are passing 2L and 12.8F arguments, then which one does Java invoke? It invokes the sum, float, float method. Why? Because, it can not invoke any other method. 2L is a long value and it cannot be passed to a integer as long is bigger than integer. If you remember from the type casting post, Java can automatically cast to a datatype upward, that is from a long to a float / double. It cannot cast automatically from a long down to integer. So, if Java cannot find an exact matching signature for a method call, it will try to use implicit casting, to cast up the value and look for a method it can call. Hence in this case Java invokes the sum, float, float method.

 

Method overloading and the Java API:

Let’s take a look at method overloading examples available in the Java API. Here we have the println() methods from the System class. Notice that there are 10 versions here and they all have different signatures.

Method overloading and the Java API

 

This allows the println() method to print different things to the console. The method basically converts a type into String in order to print it, for instance from integer to String or long to String. So, with method overloading the println() method can take variety of arguments, do the correct conversion for that argument for you and then print it out to the console.

 

Uses for method overloading:

Let’s take a look at another example of method overloading, but this time from our Shirt example. Suppose, we want to set the information for a Shirt and be able to set a variety of information, such as sometimes we might want to give the id, description and price combination or id, description, price and the color combination or id, description, price, color and  a quantity combination. Using method overloading you can provide several different methods that take several different inputs but yet have the same name for the method as logically these all methods handle the same function i.e., here to set the Shirt information.

 

 Uses for method overloading

 

It also helps the developer, in a way that if he has only 3 pieces of information, then he can use a method with 3 arguments and so on. This makes your classes more flexible. As you can see, we have done this with setShirtInfo method. We have a class called ShirtTwoTest and in the main method we have created 3 Shirt objects, shirtOne, shirtTwo and shirtThree and we have called setShirtInfo on each one of them. But we have provided different information with each call.

 

 Uses for method overloading 1

 

In the ShirtTwo class we have 3 methods with 3 different signatures. In this case they not only differ in the type of the arguments they take but also in the number of arguments that they take. What you can make out from the method signature is that the id, desc and cost arguments are available in all the method signatures but color and quantity are additionally available in methods. From this you can infer that id, desc and cost are mandatory arguments and color, quantity are optional. This is one way of creating optional arguments and its another use of method overloading.

 

 

 

Note:

 

Source: Sun Microsystems Educational Services Course – Using Decision and Looping Constructs with the Java Programming Language WJ-1103A.

 

 

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: