Java Functions (Methods)

A complete guide to methods in Java: how to declare, define, and call them, how Java passes arguments, overloading, varargs, recursion, the static vs. instance distinction, and how to document methods properly with Javadoc.

Method Declaration and Definition

In Java, a method is a named block of code that performs a specific task. All methods must be defined inside a class. A method declaration tells the compiler everything it needs to know about the method before it is called: who can access it, what it returns, what it is called, and what inputs it expects. The body that follows the declaration is the definition.

Anatomy of a method declaration

Every part of a method signature has a specific purpose. None of them is decorative.

  • Access modifier:public, private, protected, or package-private (no keyword). Controls which code can call this method.
  • static (optional):Marks the method as belonging to the class rather than to any instance. Required for methods called without an object.
  • Return type:The type of value the method sends back to the caller. Use void if the method does not return anything.
  • Method name:A camelCase identifier describing what the method does. Method names should be verbs or verb phrases: calculateTotal, sendEmail, isValid.
  • Parameter list:Zero or more typed parameters in parentheses. Even a method with no parameters must have empty parentheses: ().
  • Method body:The block of statements enclosed in braces { } that runs when the method is called.

Method Declaration and Definition

Java

Three methods illustrating different combinations of access modifiers, return types, and parameters.

Calling a Method

Calling a method transfers execution to its body. When the method finishes, control returns to the point immediately after the call expression. The way you call a method depends on whether it is static or belongs to an instance, and whether you are calling it from inside the same class or from outside.

How to call a method

The calling convention differs depending on where the method lives.

  • Static method, same class:Call by name: add(3, 5). No object required.
  • Static method, different class:Prefix with the class name: Math.sqrt(16), Integer.parseInt("42").
  • Instance method:Create an object first, then call on it: Calculator calc = new Calculator(); calc.multiply(3, 4);
  • Chaining:When a method returns an object, you can immediately call another method on the result: " hello ".trim().toUpperCase().

Calling Methods

Java

Calling static and instance methods from inside and outside the same class.

return Statement

The return statement does two things at once: it ends the method's execution and optionally sends a value back to the caller. The returned value must match the method's declared return type, or be implicitly convertible to it. The compiler checks that every possible execution path in a non-void method ends with a return statement. Missing one on any branch is a compile-time error, not a runtime one.

Multiple return points

A method can have more than one return statement. The first one reached during execution wins.

  • Multiple returns are common in methods that use guard clauses: validate inputs at the top with early returns, then handle the normal case at the bottom.
  • Some style guides prefer a single exit point. Others prefer early returns when they reduce nesting. Both are valid; pick one and be consistent.
  • In a void method, writing return; (with no value) is optional at the end of the method but can be used earlier to exit based on a condition.

return Statement with Guard Clauses

Java

Multiple return points used to handle edge cases before the main computation.

void Methods

A method declared with the return type void performs an action but does not compute and send back a value. The caller cannot use the result of a void method in an expression, because there is no result to use. Printing output, writing to a file, updating a field, and sending a network request are all actions that naturally belong in void methods.

When void is the right choice

Use void when the purpose of the method is a side effect, not a computation.

  • Output methods: printing to console, writing to a log, displaying a report.
  • Mutation methods: updating a field, sorting a list in place, resetting state.
  • Event handlers: responding to a button click, handling a network event.
  • A void method that does nothing visible and has no side effects is a code smell: ask whether it should return a value instead.

void Methods

Java

Three void methods demonstrating output, mutation, and conditional early return.

Method Parameters

Parameters are the variables listed in a method's declaration. They define what the caller must supply when invoking the method. The values the caller passes are called arguments. Parameters are local variables: they exist only for the duration of the method call and are destroyed when the method returns. You can have any number of parameters, though a method with more than four or five is usually a signal that it is taking on too many responsibilities.

Parameters vs. arguments

These two terms are often used interchangeably in conversation, but they have distinct meanings in the language specification.

  • Parameter:The variable declared in the method signature. It is a placeholder: static int add(int a, int b) -- a and b are parameters.
  • Argument:The actual value supplied at the call site: add(3, 7) -- 3 and 7 are arguments.
  • Arguments are matched to parameters by position, left to right. The types must be compatible.
  • Parameter names and the variable names used as arguments at the call site are completely independent.

Method Parameters

Java

Methods with zero, one, two, and three parameters, called with explicit arguments.

Pass by Value in Java

Java is strictly pass-by-value. Always. This is one of the most important and most misunderstood facts about the language. When you pass an argument to a method, Java copies the value of that argument into the parameter variable. For primitive types, this means the method receives a copy of the actual number or boolean. For object references, this means the method receives a copy of the reference, not the object itself. The two copies point to the same object in memory, which is where the confusion arises.

The two cases and what they mean

Understanding this distinction prevents a significant category of bugs.

  • Primitives:The method receives a copy of the value. Changing the parameter inside the method has absolutely no effect on the original variable at the call site.
  • Object references:The method receives a copy of the reference. Both the caller and the method now hold references pointing to the same object. The method CAN mutate the object's contents through that reference. But if the method assigns its copy of the reference to a new object, the caller's variable is unaffected.

Pass by Value

Java

Demonstrating that primitives are copied, and that reassigning a reference inside a method does not affect the caller.

Method Overloading

Method overloading allows you to define multiple methods with the same name in the same class, as long as they have different parameter lists. The compiler determines which version to call based on the number, types, and order of the arguments at the call site. This happens entirely at compile time. Overloading is how Java achieves one intuitive name for a family of related operations: println() is perhaps the most familiar example, with overloads for String, int, double, boolean, and every other type.

Rules for valid overloading

The compiler uses the parameter list to distinguish overloaded methods. The return type alone is never sufficient.

  • Valid distinctions:Different number of parameters, different parameter types, different order of parameter types (when the types are different).
  • Not valid:Different return type only. int add(int a, int b) and double add(int a, int b) is a compiler error. The return type is not part of what the compiler uses to resolve the call.
  • Automatic widening in overload resolution:If no exact match exists, Java widens the argument to the next compatible type. Passing an int where only a long overload exists is fine; Java widens automatically.

Method Overloading

Java

Four overloads of an area() method, each handling a different geometric shape.

Variable Arguments (varargs)

Varargs, short for variable arguments, allow a method to accept any number of arguments of the same type without requiring the caller to create an array explicitly. The syntax is the type followed by three dots: int... numbers. Inside the method body, the parameter behaves exactly like an array. The caller can pass zero arguments, one, or several, or even pass an existing array directly.

Varargs rules and restrictions

Varargs are convenient but come with specific constraints.

  • A method can have at most one varargs parameter.
  • The varargs parameter must be the last one in the parameter list. You cannot write (int... nums, String label); it must be (String label, int... nums).
  • Inside the method, use nums.length to check how many were passed, and nums[i] to access individual values.
  • Method overloading with varargs can be ambiguous. Use with care when combining overloads that differ only by whether the last parameter is varargs.

Variable Arguments (varargs)

Java

A sum method that accepts any number of int arguments, and a logger that accepts a label plus variable messages.

Recursion

A recursive method is one that calls itself. Every recursive solution consists of two parts working together: a base case that returns a result directly without further recursion, and a recursive case that breaks the problem into a smaller sub-problem and calls the method again. Without a base case, the method calls itself indefinitely until the JVM runs out of call stack space and throws a StackOverflowError.

When recursion is and is not appropriate

Recursion is elegant for problems that are naturally defined in terms of smaller versions of themselves, but it has costs.

  • Natural fits:Factorials, Fibonacci, tree traversal, directory listing, parsing nested structures.
  • Cost:Each recursive call consumes a stack frame. Very deep recursion causes StackOverflowError. Java's default stack depth is typically a few thousand frames.
  • Tail recursion:Java does not optimise tail calls. A loop equivalent is always safer for large inputs in Java.
  • Memoisation:Naive recursive Fibonacci recalculates the same sub-problems thousands of times. Caching results (memoisation) or using iteration solves this efficiently.

Recursion

Java

Factorial and Fibonacci implemented recursively, with the base case clearly separated from the recursive case.

Static Methods vs. Instance Methods

This distinction shapes how you design classes and how callers interact with your code. A static method belongs to the class itself. An instance method belongs to a specific object of the class. Choosing between them is not a style preference: it has functional consequences for what data the method can access and how it must be called.

The practical difference

The choice between static and instance is determined by whether the method needs access to object-level state.

  • Static method:Can only access static fields and other static methods directly. Has no this reference. Called on the class: ClassName.method(). Use for utility functions and factory methods that do not depend on instance state.
  • Instance method:Can access both instance fields (through the implicit this reference) and static members. Called on an object: myObject.method(). Use when the method's behaviour depends on or modifies the object's state.
  • Common design signal:If a method does not read or write any instance fields, it should very likely be static. Keeping it as an instance method forces callers to create an unnecessary object.

Static vs. Instance Methods

Java

A BankAccount class with instance methods for account-specific operations and a static utility method.

Method Signatures

A method's signature is its name plus its parameter list: specifically the number of parameters, their types, and their order. The return type and access modifier are not part of the signature. The JVM uses the signature to uniquely identify a method within a class. This is why two methods can share the same name as long as their signatures differ, and why two methods cannot share the same name with identical parameter types even if one returns int and the other returns double.

Signature components

Knowing exactly what is and is not part of a signature explains both overloading rules and compiler error messages.

  • Part of the signature:Method name, parameter count, parameter types (in order).
  • NOT part of the signature:Return type, access modifier (public/private), static keyword, parameter names, throws clause.
  • Practical consequence:The compiler error "method is already defined" means two methods have identical signatures. Changing only the return type will not resolve it.
  • Erasure and generics:After compilation, generic type information is erased. List and List have the same erased type (List), so you cannot overload based on generic type parameters alone.

Method Signatures

Java

Valid and invalid overloads illustrating exactly what constitutes a distinct signature.

Javadoc Comments for Methods

Javadoc comments document the contract of a method: what it expects, what it returns, and what can go wrong. They are written directly above the method declaration using the /** ... */ syntax. The javadoc tool reads these comments and generates HTML documentation. IDEs like IntelliJ and VS Code also surface Javadoc content as hover tooltips, which makes well-written Javadoc immediately useful to every developer calling the method.

Standard Javadoc tags for methods

Each tag has a specific purpose. Only include tags that are relevant to the method.

  • @param name description:Documents one parameter. Write one @param tag per parameter in the order they appear in the signature.
  • @return description:Documents the return value. Omit for void methods.
  • @throws ExceptionType description:Documents an exception the method may throw. Include both checked and important unchecked exceptions.
  • @since version:Indicates which version of the API introduced this method.
  • @deprecated reason:Marks the method as deprecated and explains the preferred alternative.

Javadoc Comments

Java

Well-documented methods showing the summary line, @param, @return, and @throws tags.

Command-line Arguments in main()

The String[] args parameter in the main method receives any arguments passed to the program on the command line. Each space-separated token becomes one element in the array. Everything arrives as a String: if you need a number, you must parse it using Integer.parseInt() or Double.parseDouble(). Always check args.length before accessing any element, because failing to do so causes an ArrayIndexOutOfBoundsException when the program is run without the expected arguments.

How command-line arguments work

Understanding args lets you write programs that behave differently based on how they are launched.

  • java Main Alice 30, args[0] is "Alice", args[1] is "30", args.length is 2.
  • java Main, args is an empty array. args.length is 0, not a NullPointerException.
  • Arguments containing spaces must be wrapped in quotes in the terminal: java Main "Alice Smith" 30.
  • Parsing failure: if the user passes "abc" where an int is expected, Integer.parseInt throws NumberFormatException. Always handle this gracefully.

Command-line Arguments

Java

A calculator that reads its two operands and operator from args, with validation and usage instructions.

Quiz - Test Your Knowledge

Ten questions covering method declaration, pass-by-value, overloading, varargs, recursion, static vs. instance methods, signatures, Javadoc, and command-line arguments. Read each option carefully before answering.

Knowledge Check

1. What is the correct way to declare a method that takes two ints and returns their sum?

2. Java passes primitive arguments to methods by:

3. Which of the following is NOT a valid basis for method overloading?

4. What does the varargs declaration int... numbers allow?

5. What are the two necessary conditions for a recursive method to work correctly?

6. Which statement about static methods is correct?

7. What constitutes a method signature in Java?

8. What happens when you pass an object reference to a method in Java?

9. Where must a varargs parameter appear in a method's parameter list?

10. Which Javadoc tag documents what a method returns?