Java Method

In this article, we’ll talk about Java Method. More specifically, you will learn how you can declare, call and apply the best practices when it comes to methods.

1. What is a Java Method?

A Java method is just a block of code that ought to have a single responsibility and may or may not return a value. Furthermore, a method can be called by other methods or it can even call itself recursively. Finally, methods are used in order to eliminate duplication and enhance the readability of code.

2. Java Method Syntax

In this section, we’ll look at the minimum components that a method declaration needs to compile and then take a brief look at all the possible keywords that we can add.

2.1 Basic Syntax

When declaring a method, the only mandatory information that you must provide is the name of the method, return type, and any parameters that it might accept(it can accept zero, one or more parameters):

return_type methodName(Type1 param1, Type2 param2, ..., TypeN paramN) {
  //Method implementation
}

Let’s analyze the syntax a little:

  • The return type can be void or any type of object that you might like.
  • When using the keyword void, you will never be able to return a value back to the caller, however, you can stop the method execution at any point by just typing return;
  • If you chose that the method should return a value, you must always return a value that matches the type of the return_type. To return a value, you just type return, followed by the variable name you want to return.
  • The name of each parameter must be unique

As a result, a method declared as this would compile without any problem:

void print(String s) {
  System.out.println(s);
}

Likewise, the following would work:

String toUppercase(String s) {
  return s.toUpperCase();
}

2.2 Syntax with All Options

In the previous section, we saw the minimum requirement when declaring a method. Nevertheless, we can add many more keywords in order to specify the specific characteristics of this method.

In the following snippet, you can see all the keywords that we can add when declaring a method but note that there are some rules on when you can use them together or not.

[access_modifier -> default(no keyword) or public or protected or private] [generic type] [final] [abstract] [default] [native] [static] [synchronized] return_type methodName(Type1 t1, Type2 t2, ..., TypeN tN) [throws Any_type_of_Exception1, Any_type_of_Exception2, ... Any_type_of_ExceptionN]

While this syntax might be overwhelming, we will explain in a later section how and why we would use any of these keywords.

3. Java Method Signature

You can think of method signature as a way to identify uniquely a method that you have declared. More specifically, if someone asks you to provide a signature this method:

public static void printFromFile(String fileName) throws IOException {
  //code to print from file
}

You would just write: public static void printFromFile(String) throws IOException

With this in mind, since the method signature is unique, you will never be able to create another method with the same signature

4. Java Method Example

Let’s say that you need to create a public method(since we need to be able to call it in any class) that accepts a ticker of a stock(e.g. AAPL), the price that you bought this stock, the trading fee, and the tax percentage. You could have something like this:

public class PnL {
    
    private final StockClient stockClient = new StockClient();
    
    public double calculatePnL(String ticker,
                               double priceBought,
                               double tradingFeeOfTransaction,
                               double taxPercent
) {
        double earningsOrLossBeforeTax = getCurrentPriceOfStock(ticker) - priceBought- tradingFeeOfTransaction;
        return earningsOrLossBeforeTax > 0 ? 
                earningsOrLossBeforeTax * (1 - taxPercent) : 
                earningsOrLossBeforeTax;
    }

    private double getCurrentPriceOfStock(String ticker) {
        return stockClient.getCurrentPrice(ticker);
    }
}

Here we created an additional private method, as we do not want it to be accessed by another class, that gets the live price of a ticker.

Now if we want to use this method, we could do it like this:

PnL pnl = new PnL();
double earnings = pnl.calculatePnL("AAPL", 100d, 0.5d, 0.15d);

And with the price of 134 as of the time of writing, we would get a net profit~= 28.5 USD.

Of course, note that this works with just one stock and if we needed more, we would need to add another parameter, e.g. units, to specify how many stocks we hold.

5. How to Call a Method in Java

To call a method, you just have to type the method name followed by parentheses that must have all the required arguments. For example, let’s say you have created this method in Math.java:

public int abs(int x) {
  return x <=0 ? -x : x;
}

If you like to call this method for the number -5, you just write the following:

Math math = new Math();
math.abs(-5);

This means that you need to first create an object and then call the method, in case the method is not static.

On the other hand, if the method was declared as static, we could call them like this, without any need to create an object:

Math.abs(-5);

Last but not least, if the method is called from the same class, you do not need to use an object to call it:

public class Main {
    
    public static void main(String[] args) {
        Main main = new Main();
        main.hello();
    }

    void hello(){
        hey();
    }
    
    void hey(){
        System.out.println("Hey");
    }
}

As you can see, we called the hey() method inside the hello(), without using any object other than the initially created object inside main.

6. Java Method Naming Convention

In Java, the naming convention for methods is camel-case, with the first letter lowercase.

Let’s say we have a method that converts an object to JSON, we should name it like this:

String objectToJson(Object object){} OR
String toJson(Object object){} 

but never like this:

String ObjectToJson(Object object){} OR
String OBJECTTOJSON(Object object){} OR
String object_to_json(Object object){} 

7. Java Method Types

In this section, we will see all the method types that exist, based on adding extra keywords

7.1 Access-Restricted Methods

Based on adding public , private , protected or nothing, you specify the visibility of a method:

  • public means any class can access it
  • protected means that only classes in the same package and subclasses can access it
  • private means it can be accessed that it can only be accessed from the same class
  • no keyword means that it is package-private

To completely understand how access modifiers work, I suggest that you read Access Modifiers in Java.

7.2 Generic Methods

Generic methods allow you to have parameters of a type that can be chosen when the method is called. For example:

public <T> void print(T t) {
  System.out.println(t);
}

Can print any object that you can imagine. Of course, if you like to delve into Generics, you should read Java Generics.

7.3 Abstract Methods

Abstract methods are just methods without any implementation and you can only define them inside abstract classes or interfaces.

Additionally, since abstract methods have no implementation, they cannot be static nor final.

Finally, to really grasp how abstract methods work, you should read Java Abstract Class & Java Interface.

7.4 Final Methods

Final methods are just methods that can never be overridden in a subclass; read more about the final keyword in Final Keyword in Java.

7.5 Default Methods

Default methods were introduced in Java 8, and you can only use them inside Interfaces.

Their purpose is to have a default implementation inside an interface that can be overridden later by a class that implements this interface.

7.6 Static Methods

Static methods do not need any object instantiation and they can just be called by using the class name.

Additionally, static methods cannot be overridden, cannot be abstract, cannot access instance members and you cannot use the keyword this and super with them.

Last but not least, you should use them when you do not have any dependency on objects and when creating utility and helper methods.

7.7 Synchronized Methods

Synchronized methods are used in multithreaded environments and more specifically when a method should only be accessed by one thread at a time.

This means that if a thread accesses a synchronized method, it locks it until it finishes, making it impossible for another thread to interfere.

8. Is Java Pass by Value or Pass by Reference?

This is a classic Java interview question, for which the answer is by value.

Now consider the example below:

public static void main(String[] args) {
    int a = 5, b = 6;
    add(a, b);
    System.out.println(a);
    System.out.println(b);
}

public static void add(int a, int b){
    a++;
    b++;
}

You can see that we added 1 to both numbers passed as arguments, and after the method returns, we print the result. Here it is important to note that we do not actually pass any reference but just the copy of the values(5 and 6), and as a result, the values assigned to a and b will never change outside the scope of the add method, and the output will be the following:

5
6

On the other hand, if we had defined a class like the one shown below:

public class Pair {
    private int a;
    private int b;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }
}

And then we do the following:

public static void main(String[] args) {
    Pair pair = new Pair(5, 6);
    add(pair);
    System.out.println(pair.a);
    System.out.println(pair.b);
}

public static void add(Pair pair){
    pair.setA(pair.getA() + 1);
    pair.setB(pair.getB() + 1);
}

This time, the reference of the object(which is just a value that represents the memory location) will be passed and the values that its attributes have will actually change and the following will be printed:

6
7

With this in mind, you should always be careful how and what variables you pass as arguments so that you will always get the expected results

9. Java Method Overloading

Method overloading is when we define multiple methods with the same name but with a different signature. Different signature means that either the type of the parameters and/or the number of the parameters is different between them.

Note that changing the return type is not enough to differentiate two methods.

Finally, you should know that this type of polymorphism always happens in compile time. Here is an example:

public void printPersonInfo(String name){}

public void printPersonInfo(String name, String surname){}

public void printPersonInfo(String name, String surname, double salary){}

All of the methods above are valid as although they have the same name, they have a different number of methods. Of course, they could just have different types and/or order of parameters and they would still be valid; so if we add this method, the code would compile as expected.

public void printPersonInfo(String name,double salary ,String surname){}

10. Java Method Overriding

Method overriding is when we define multiple methods with the same name, same signature, and return type in order to “ignore” the previously defined methods in a parent class or interface.

Unlike method overloading, this type of polymorphism only happens on run-time.

Here is an example:

public class Animal {

    void makeASound(){
        System.out.println("AAA");
    }
}

public class Cat extends Animal {

    @Override
    void makeASound() {
        System.out.println("Meow");
    }

}

public class Dog extends Animal {

    @Override
    void makeASound() {
        System.out.println("Woof");
    }

}

Here you can notice that the implementation of makeASound method is overridden in the subclasses Cat and Dog since we know the specific sound these animals produce.

Additionally, you should notice the @Override annotation whose purpose is to produce a compile time error in case the annotated method is not actually overridden.

Finally, if you like to become an Object Oriented Programming expert you should read all these articles:

11. Java Method with Optional Parameters – Varargs

Although in the previous sections, we stated that we need to always pass the arguments that the method signature requires, there is one exception, in which you can omit to add a specific parameter.

Varargs are effectively an array but you need to use the three-dot notation, along with the type of the parameter; for example, if you want a method that accepts 0, 1, or n Strings, you should declare it as shown below:

public static void printVarargs(String... args) {
    for (String s : args) {
        System.out.println(s);
    }
}


public static void main(String[] args) {
    printVarargs();
    printVarargs("You");
    printVarargs("You", "Learn");
    printVarargs("You", "Learn", "Code");

}

As you can see, we called the method with 0, 1, 2, and 3 arguments, and the compiler will not complain.

All in all, you should consider that if you choose to use varargs, you have 2 limitations:

  • You can use only one varargs parameter per method
  • The varargs parameter must always be the last in order

12. Java Method Reference

Java Method Reference was introduced in Java 8, along with Lambdas, and is the most concise way to call a method.

First of all, the syntax is the following:

Class_or_object::a_method

and this will always return a Java 8 Function/Predicate/Consumer etc.

For example, the following method reference returns the sum of two numbers:

BinaryOperator<Integer> integerSum = Integer::sum;

In the above example, we refer to the sum method of the Integer class by using the :: operator.

If you needed to create a method reference that adds 4 integers and returns the result since there isn’t such a method in Integer class, you would have to create your own as shown below:

public static void main(String[] args) {
    FourSum fourSum =  MethodReference::sum;
}

@FunctionalInterface
public interface FourSum {

    Integer sum(int a, int b, int c, int d);
}

public static int sum(int a, int b, int c, int d) {
    return a + b + c + d;
}

Finally, to learn more about Java 8 Lambda Expressions and Method References, you should read Java Lambda Expressions.

13. Conclusion

By now you should know what a method is in Java, what is the syntax of a method, what is a method signature and more importantly how to call a method. Moreover, you learned about the naming convention, how overloading and overriding work, and the various types of methods that exist.