skip to content

What exactly constitutes a method signature in Java, and what is deliberately excluded from it?

level: middleimportance: must knowfreq 80%

answer

  1. Signature = name + parameter types (in order)
  2. Return type is NOT in the signature
  3. Parameter names, modifiers, throws all excluded
  4. Can't overload on return type alone → duplicate method
  5. JVM descriptor DOES include return type (different concept)

basics

~10 s

A method's signature is its name plus the number, types, and order of its parameters. The return type, parameter names, modifiers, and throws clause are NOT part of the signature.

solid answer

~40 s

In Java a method signature is the method name together with the parameter types in order — formally, the name plus the ordered list of formal parameter types (and, for generic methods, the type parameters). Crucially, the return type, the parameter names, access/other modifiers, and the throws clause are all excluded. This is why you cannot overload two methods that differ only by return type: the compiler would see identical signatures and reject them as a duplicate. It is also why overloading works by varying the parameter list. The signature is what the compiler uses to match a call site to a method and to distinguish overloads; the JVM's internal 'descriptor' does include the return type, but that is a separate, lower-level concept from the language-level signature the JLS defines.

go deeper

for a junior

Knows the signature is roughly the method name and its parameters.

for a middle

States precisely name + ordered parameter types, knows return type/names/modifiers/throws are excluded, and connects this to overloading rules.

for a senior

Explains the override-matching role (with covariant returns) and can contrast the language signature with the JVM descriptor that includes the return type.

for a principal

Reasons about API/ABI compatibility: which signature changes are source- vs binary-compatible, bridge methods from generics/covariance, and why the language deliberately excludes the return type.

## Definition The **method signature** (as defined by the Java Language Specification) is: - the **method name**, plus - the **number, types, and order of its formal parameters** (the parameter types only — *not* their names), plus - for generic methods, the **formal type parameters**. For `int transfer(Account from, Account to, BigDecimal amount)` the signature is conceptually `transfer(Account, Account, BigDecimal)`. ## What is explicitly NOT part of the signature - **Return type** — `int f()` and `String f()` have the *same* signature. - **Parameter names** — `f(int a)` and `f(int b)` are identical signatures. - **Access and other modifiers** — `public`, `static`, `final`, etc. do not contribute. - **The `throws` clause** — declared exceptions are not part of it. - **Annotations** on the method or parameters. ## Why the exclusions matter: overloading **Overloading** means two methods in the same class share a name but differ in their parameter lists. Because the signature is name + parameter types, two overloads must differ in parameter *types/count/order*. A direct consequence: ```java int parse(String s) { ... } double parse(String s) { ... } // COMPILE ERROR: same signature ``` These differ only in return type, so they have the *same* signature and the compiler reports a duplicate method. Differing only by parameter *name* fails for the same reason. ## Signature vs override For a subclass method to **override** a superclass method, it must have the same signature (an exception is *covariant return types*: the override may return a subtype, but the parameter types must match). So 'same signature' is the gate for both overload-collision and override-matching. ## Signature vs JVM descriptor At the bytecode level the JVM identifies a method by name **plus a descriptor that DOES include the return type** (e.g. `(Ljava/lang/String;)I`). That lets the JVM (and tools/bridge methods) distinguish things the *language* signature cannot. But when an interviewer asks about the 'signature' they mean the JLS language-level concept, which excludes the return type. Knowing both, and not conflating them, is the senior-level nuance. ## Practical impact - Designing an API: you cannot use return type to disambiguate; vary parameters or rename. - Overload resolution operates on signatures at compile time, choosing the most specific applicable one. - Refactoring parameter *names* is binary- and source-compatible; changing parameter *types* or order changes the signature and can break callers and overrides.

  • Why can't Java overload methods that differ only in return type?
    Because the return type is not part of the signature, two such methods have identical signatures, which the compiler rejects as a duplicate method. The call site result might also be discarded (e.g. in an expression statement), leaving no way to choose.
  • Does the parameter name affect overload resolution?
    No. Only the parameter types and their order matter. Renaming a parameter leaves the signature unchanged and is source/binary compatible.

saying these in an interview costs you the question

  • Saying the return type is part of the signature
  • Believing you can overload methods that differ only by return type
  • Including parameter names or the throws clause in the signature
  • Conflating the JLS signature with the JVM bytecode descriptor without noting the difference

context