skip to content

Variable Shadowing

Shadowing is an inner-scope name hiding an outer one, most often a constructor parameter hiding a field, which is why this.field exists. Interviewers use it in short output-prediction snippets.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is variable shadowing in Java, and can you give a common example?

level: juniorimportance: must knowfreq 70%

answer

  1. Inner scope hides same-named outer variable
  2. Name resolves innermost-first
  3. Classic: parameter vs field
  4. this.field reaches the shadowed field
  5. this.name = name is the idiom

basics

~20 s

Shadowing happens when a variable in an inner scope has the same name as one in an outer scope, so the inner one hides the outer one. A classic case is a constructor parameter named the same as a field.

solid answer

~40 s

Variable shadowing occurs when a variable declared in a narrower (inner) scope has the same name as a variable in an enclosing (outer) scope. Inside the inner scope the bare name refers to the inner variable, so the outer one is temporarily hidden, or shadowed. The most common example is a constructor or setter whose parameter has the same name as a field: inside the method, the plain name refers to the parameter, not the field. To reach the shadowed field you qualify it with this, as in this.name = name. Shadowing is legal Java and often intentional, since it keeps parameter names meaningful, but accidental shadowing can cause bugs where you read or write the wrong variable.

code

java · 10 lines
java
class Person {
    private String name;
    Person(String name) {       // parameter shadows the field
        this.name = name;       // this.name = field, name = parameter
    }
    String describe() {
        String name = "local";  // local shadows the field here
        return name + " / " + this.name; // "local / <field value>"
    }
}

go deeper

for a junior

Can define shadowing, recognize the parameter-vs-field case, and fix it with this.field = field.

for a middle

Explains name resolution as innermost-first, distinguishes shadowing from overriding/hiding, and spots accidental shadowing in review.

for a senior

Discusses where shadowing is idiomatic vs risky, the local-vs-local error rule, and lints/conventions that catch accidental shadowing.

for a principal

Frames shadowing within language scope-resolution rules, weighs team naming conventions and static-analysis policy, and teaches the distinction from field hiding cleanly.

## Scope first In Java, every variable lives in a **scope** — the region of code where the name is visible. Scopes nest: a method body sits inside a class, a loop body sits inside a method, and so on. An **inner** (or narrower) scope is one nested inside an **enclosing** (outer) scope. ## What shadowing is **Variable shadowing** is when you declare a variable in an inner scope with the **same name** as a variable that already exists in an enclosing scope. Java resolves a bare (unqualified) name by searching from the innermost scope outward and stopping at the **first** match. So inside the inner scope, the name refers to the **inner** variable; the outer variable still exists but is **hidden** — you cannot reach it by its plain name. The outer variable is said to be *shadowed*. ## The canonical example: parameter shadows a field A **field** (also called an instance variable) is a variable declared directly in a class. A **parameter** is a variable declared in a method's signature. When both have the same name, inside that method the name means the **parameter**: ```java class Person { private String name; // field Person(String name) { // parameter shadows the field name = name; // BUG: assigns the parameter to itself; field untouched } } ``` The line `name = name` does nothing useful: both sides refer to the parameter. The field stays null. ## Disambiguating with `this` `this` is a reference to the current object. `this.name` always means the **field** `name` of the current object, regardless of any shadowing local variable or parameter. So the fix is: ```java Person(String name) { this.name = name; // left = field, right = parameter } ``` This idiom — parameter named like the field, `this.field = field` — is extremely common and considered idiomatic, not a smell. ## Where shadowing can appear - A **parameter** shadowing a field (most common). - A **local variable** shadowing a field. - A local variable or parameter shadowing an inherited field from a superclass. Note: Java does **not** let two locals in *overlapping* block scopes share a name (that is a compile error), so a local cannot shadow another local in the same nested-block chain — shadowing is between a local/parameter and a **field**, or across class scopes. ## Why it matters Intentional shadowing keeps parameter names readable. Accidental shadowing is a classic source of silent bugs: you think you are touching the field but you are touching the local. Knowing that bare names resolve innermost-first, and that `this.x` reaches the field, lets you read and fix such code with confidence.

  • Why does name = name in a constructor leave the field null?
    Both occurrences resolve to the parameter (innermost scope wins), so it assigns the parameter to itself; the field is never written and keeps its default null.
  • Is shadowing a parameter over a field bad practice?
    No. It is idiomatic when paired with this.field = field. It only becomes a problem when accidental and the field reference is forgotten.

Like a local nickname overriding a person's legal name in a small room: while you're in the room, the nickname wins; step out (use this) to use the legal name.

saying these in an interview costs you the question

  • Saying shadowing is a compile error (it is legal Java)
  • Confusing shadowing with overriding (overriding is for methods/polymorphism)
  • Thinking the outer variable is destroyed rather than just hidden
  • Believing two locals in overlapping scopes can shadow each other (that is an error)

context

open as a page

How does Java decide which variable a bare name refers to when a field and a local of the same name both exist?

level: middleimportance: must knowfreq 55%

basics

~20 s

Java looks at the closest (innermost) scope first. If a local variable or parameter has the name, that wins; the field is only used if no closer variable has the name. Use this.name to force the field.

open as a page

What bugs can accidental variable shadowing cause, and how do you prevent or detect them?

level: middleimportance: should knowfreq 40%

basics

~10 s

Accidental shadowing makes you read or write the wrong variable, like a setter assigning a parameter to itself so the field never updates. Prevent it with this.field, clear names, and compiler warnings or linters.

open as a page

What restriction does Java place on lambdas and inner classes regarding shadowing local variables, and why?

level: seniorimportance: should knowfreq 35%

basics

~20 s

A lambda cannot declare a parameter or local with the same name as a variable already in scope in the enclosing method; that is a compile error. Anonymous and local inner classes also capture effectively-final locals and cannot redeclare them.

open as a page

How does variable shadowing differ from field hiding and from method overriding?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Shadowing is a local or parameter hiding a same-named field in one scope. Field hiding is a subclass field hiding a superclass field of the same name. Overriding is about methods and is chosen at runtime. Only overriding is polymorphic.

open as a page