Java Cheatsheet

Methods

Use this Java reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Method Declaration Syntax

[modifiers] returnType methodName([params]) [throws ExceptionList] {
    // body
}
// Basic examples
public int add(int a, int b) { return a + b; }
private void log(String msg) { System.out.println(msg); }
protected static double circle(double r) { return Math.PI * r * r; }

Modifiers Summary

ModifierEffect
publicAccessible from anywhere
protectedAccessible in same package + subclasses
privateAccessible only within the same class
(none)Package-private (same package only)
staticBelongs to the class, not an instance
finalCannot be overridden in subclasses
abstractNo body; subclass must implement
synchronizedThread-safe; one thread at a time
nativeImplemented in native code (JNI)
strictfpStrict floating-point (deterministic, rarely used)

Parameters

// Positional parameters
public double pow(double base, int exponent) { ... }

// Varargs — must be last parameter, treated as array inside
public int sum(int... nums) {
    int total = 0;
    for (int n : nums) total += n;
    return total;
}
sum(1, 2, 3);          // 3 args
sum(new int[]{1,2,3}); // array also works

// Passing arrays
public void printAll(String[] arr) { ... }

// Passing by value vs. reference
// Primitives: copy passed — caller's variable unchanged
// Objects: reference copy — caller sees mutations to the object's fields
void modify(int x)   { x = 99; }         // caller's int unchanged
void modify(int[] a) { a[0] = 99; }      // caller's array[0] IS changed

Return Types

// void — no return value
public void print(String s) { System.out.println(s); }

// Primitive
public int length(String s) { return s.length(); }

// Object
public String toUpper(String s) { return s.toUpperCase(); }

// Multiple values — use a record or array
public record MinMax(int min, int max) {}
public MinMax minMax(int[] arr) {
    return new MinMax(Arrays.stream(arr).min().getAsInt(),
                      Arrays.stream(arr).max().getAsInt());
}

// Early return
public int abs(int n) {
    if (n < 0) return -n;
    return n;
}

Method Overloading

Same name, different parameter types or count. Return type alone is NOT sufficient.

public class Printer {
    public void print(int n)    { System.out.println(n); }
    public void print(double d) { System.out.println(d); }
    public void print(String s) { System.out.println(s); }
    public void print(String s, int times) {
        for (int i = 0; i < times; i++) System.out.println(s);
    }
}

Static Methods

public class MathUtils {
    public static int factorial(int n) {
        if (n <= 1) return 1;
        return n * factorial(n - 1);
    }
}

// Called on the class, not an instance
int f = MathUtils.factorial(5);  // 120

Recursion

// Factorial
public static int factorial(int n) {
    if (n == 0) return 1;               // base case
    return n * factorial(n - 1);        // recursive case
}

// Fibonacci (naive)
public static int fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}

// Tail-recursive style (JVM does NOT optimize tail calls)
public static int factorial(int n, int acc) {
    if (n == 0) return acc;
    return factorial(n - 1, n * acc);
}

Lambda Expressions (Java 8+)

// Syntax: (params) -> expression  or  (params) -> { statements; }
Runnable r  = () -> System.out.println("run");
Comparator<String> cmp = (a, b) -> a.compareTo(b);
Function<Integer, Integer> sq = x -> x * x;
BiFunction<Integer,Integer,Integer> add = (a, b) -> a + b;

// Multi-statement body
Function<String, Integer> parse = s -> {
    System.out.println("parsing: " + s);
    return Integer.parseInt(s);
};

// Using them
List<String> names = new ArrayList<>(List.of("Bob", "Alice", "Carol"));
names.sort((a, b) -> a.compareTo(b));
names.forEach(n -> System.out.println(n));

Method References (Java 8+)

Shorthand for lambdas that simply call a method.

SyntaxEquivalent LambdaExample
Class::staticMethod(args) -> Class.method(args)Integer::parseInt
instance::method(args) -> inst.method(args)System.out::println
Class::instanceMethod(obj, args) -> obj.method(args)String::toLowerCase
Class::new(args) -> new Class(args)ArrayList::new
List<String> words = List.of("hello", "world");
words.stream()
     .map(String::toUpperCase)          // Class::instanceMethod
     .forEach(System.out::println);     // instance::method

List<Integer> nums = List.of("1","2","3")
    .stream()
    .map(Integer::parseInt)             // Class::staticMethod
    .collect(Collectors.toList());

Supplier<List<String>> factory = ArrayList::new; // constructor ref

Functional Interfaces (java.util.function)

InterfaceMethod SignatureUse
Runnablevoid run()No args, no return
Supplier<T>T get()Produce a value
Consumer<T>void accept(T t)Consume a value
BiConsumer<T,U>void accept(T t, U u)Consume two values
Function<T,R>R apply(T t)Transform T → R
BiFunction<T,U,R>R apply(T t, U u)T, U → R
Predicate<T>boolean test(T t)Test/filter
BiPredicate<T,U>boolean test(T t, U u)Test two values
UnaryOperator<T>T apply(T t)T → T (same type)
BinaryOperator<T>T apply(T t1, T t2)(T,T) → T
Comparator<T>int compare(T o1, T o2)Order two values
Predicate<String> isEmpty = String::isEmpty;
Predicate<String> notEmpty = isEmpty.negate();
Predicate<String> longEnough = s -> s.length() > 5;
Predicate<String> valid = notEmpty.and(longEnough);

Function<String, Integer> len = String::length;
Function<Integer, String> str = Object::toString;
Function<String, String> lenStr = len.andThen(str);   // compose

Default and Static Interface Methods

interface Greeter {
    String greet(String name);                        // abstract

    default String greetLoudly(String name) {         // default — can override
        return greet(name).toUpperCase();
    }

    static Greeter formal() {                         // static factory
        return name -> "Good day, " + name;
    }
}

Custom @FunctionalInterface

@FunctionalInterface
interface Transformer<T, R> {
    R transform(T input);
    // Only one abstract method allowed
}

Transformer<String, Integer> len = String::length;

Passing and Returning Functions

// Higher-order: accept a function
public static <T> List<T> filter(List<T> list, Predicate<T> pred) {
    return list.stream().filter(pred).collect(Collectors.toList());
}

// Higher-order: return a function
public static Predicate<Integer> greaterThan(int threshold) {
    return n -> n > threshold;
}

List<Integer> big = filter(nums, greaterThan(10));

Method Signature Gotchas

// Overloading vs. overriding
// Overload: same class, different signature → resolved at compile time
// Override: subclass replaces parent method with same signature → runtime dispatch

// Covariant return types (override can narrow the return type)
class Animal { Animal create() { return new Animal(); } }
class Dog extends Animal {
    @Override Dog create() { return new Dog(); }  // valid
}

// Checked exceptions — overriding method cannot declare broader checked exceptions
class Base {
    void method() throws IOException { ... }
}
class Child extends Base {
    @Override void method() throws FileNotFoundException { ... }  // OK — narrower
    // @Override void method() throws Exception { ... }          // ERROR — broader
}

Calling Conventions

// Named / positional (Java has only positional)
add(3, 5);

// Chain (fluent API)
StringBuilder sb = new StringBuilder()
    .append("Hello")
    .append(", ")
    .append("World");

// super call
class Child extends Parent {
    @Override void greet() {
        super.greet();     // call parent version
        System.out.println("Child greeting");
    }
}