Q9 of 40 · Core Java

What is the difference between throw and throws in Java?

Core JavaJuniorjava-exceptionsthrowthrowschecked-exceptionsjava-fundamentals

Short answer

Short answer: `throw` is a statement that actually raises an exception at runtime. `throws` is a declaration in a method signature that warns callers this method may propagate a checked exception. `throw` is action; `throws` is a contract.

Detail

throw and throws look almost identical but serve completely different purposes.

throw is an executable statement. When the JVM reaches a throw statement, it immediately stops normal execution, creates (or re-throws) an exception object, and begins unwinding the call stack looking for a matching catch block. You use it to signal that something has gone wrong: throw new IllegalArgumentException("id must be positive").

throws appears in a method signature and is a compile-time contract. It tells the compiler — and callers — that this method may propagate a checked exception that the caller must handle or declare in its own throws clause. It does not cause the exception to be thrown; it just documents the possibility. Unchecked exceptions (RuntimeException and its subclasses) can be thrown without a throws declaration — the compiler doesn't force you to declare them.

Why this matters in test code: test methods in JUnit 5 can declare throws Exception in their signature. This lets you call checked-exception-throwing code directly without try-catch boilerplate — JUnit catches and reports the exception as a test failure. Without the throws declaration, you'd need a try-catch in every test, cluttering the assertion logic.

The distinction also matters when reading stack traces: throw is the line that caused the exception; throws is just the declaration that propagated it.

// EXAMPLE

ThrowVsThrows.java

import java.io.IOException;

// throws — contract: caller must handle or re-declare IOException
public String readConfig(String path) throws IOException {
    return Files.readString(Path.of(path)); // may throw IOException
}

// throw — action: raise exception right now
public int parsePort(String value) {
    int port = Integer.parseInt(value);
    if (port < 1 || port > 65535) {
        throw new IllegalArgumentException(
            "Port must be 1-65535, got: " + port);
    }
    return port;
}

// JUnit 5 test: declare throws Exception to avoid try-catch boilerplate
@Test
void configFileIsReadable() throws IOException {
    String content = readConfig("src/test/resources/config.json");
    assertThat(content).contains("baseUrl");
    // IOException propagates to JUnit if thrown — reported as test failure
}

// WHAT INTERVIEWERS LOOK FOR

Clear one-sentence definitions of each (statement vs declaration), understanding that throws only applies to checked exceptions, and a practical application in test code. JUnit's throws Exception pattern is a strong applied example.

// COMMON PITFALL

Saying 'throws causes an exception to be thrown'. It doesn't — it only declares that one might propagate. The exception is only raised when a throw statement executes.