Variable Scope - Java

  1. What is the result of compiling and running this program?
    Answer: It fails compilation because the right side of the initializer reads the not-yet-assigned local variable. When Java encounters a local variable declaration like int value = value + 1, it must resolve what value refers to on the right-hand side. This is a question about variable scope and the forward-reference rule: the moment a local variable is declared, its name immediately shadows any same-named field in the enclosing class — even before the initializer finishes executing. Here's the key: Java's compiler sees int value and registers the local variable in scope. When it then tries to evaluate value + 1 on the right side, it resolves value to the local variable itself — not the static field. But that local variable hasn't been assigned yet, so the compiler rejects it with an "variable value might not have been initialized" error. The program fails to compile, making D correct. Choice A is wrong because the static field ScopeTest.value is not what the compiler resolves on the right side — the local variable shadows it the moment the declaration begins. Choice B describes a behavior from some other languages (like C#'s definite-assignment rules or C's zero-initialization), but Java does not default-initialize local variables to zero automatically; that only applies to instance and static fields. Choice C is a red herring — accessing a static field without qualification inside the same class is perfectly legal in Java; that's not the issue here. A good rule of thumb: whenever you see a local variable initialized using its own name, ask yourself what the compiler resolves that name to. In Java, local variable scope begins at the point of declaration, creating a self-referential uninitialized read — a compile-time error every time.
  2. What is the result of compiling and running this program?
    Answer: It fails compilation because next is outside its scope in the while condition. When you see code involving loops in Java, always ask yourself: where exactly is each variable declared, and what is its scope? A variable declared inside a block — any pair of {} — only exists within that block and disappears the moment execution leaves it. In this code, next is declared inside the do block's braces. That means it is created fresh on each iteration and ceases to exist when the closing } is reached. The while (next < 3) condition sits outside that closing brace, so by the time Java evaluates the condition, next is already out of scope. The compiler catches this immediately and refuses to compile — making C the correct answer. Choice A is tempting because the logic sounds reasonable — three iterations, print 3 — but it assumes the code compiles, which it never does. Choice B makes a similar mistake by imagining runtime behavior ("discarded after the first iteration") when the program never even reaches execution. Choice D identifies a compilation failure, which is partially on the right track, but misidentifies why it fails. The issue is not that next might be uninitialized; it is initialized on every iteration. The real problem is that the variable simply doesn't exist at the point where the while condition tries to use it. A good rule of thumb: in Java, a variable's scope begins at its declaration and ends at the closing brace of the block containing it. Whenever you see a variable used outside its declaring block — even one line below that closing brace — expect a compilation error.
  3. What is the result of compiling and running this program?
    Answer: It prints CD because the catch parameter's scope ends with the catch block. When you see a question involving variable names appearing in both a catch clause and the surrounding method body, think carefully about variable scope — specifically, where each variable "lives" and dies. In Java, a catch clause's parameter (like ex here) is scoped exclusively to that catch block. Once the closing brace } of the catch block is reached, that ex variable ceases to exist entirely. This means declaring a new RuntimeException ex afterward in the same method is perfectly legal — it's a brand-new variable in the enclosing method scope, with no conflict whatsoever. The program catches the IllegalStateException (which is a subtype of RuntimeException, so the catch matches), prints "C", exits the catch block, then continues to declare the new ex, prints "D", and exits normally. Answer B is correct. Answer A is wrong because catching an exception does not terminate the method. Execution continues normally after the catch block — that's the whole point of exception handling. Answer C is wrong because there is no conflict. Since the catch parameter's scope ends before the new declaration begins, the compiler sees two entirely separate variables that never overlap. Answer D tempts students who assume variable names must be unique across an entire method. But Java's scoping rules are block-based, not method-wide. A catch parameter and a local variable can share the same name as long as their scopes don't overlap — and here they don't. Study tip: Always trace variable scope block by block. A catch parameter lives only inside its catch block — outside it, that name is free to be reused.
  4. What is the result of compiling and running this program?
    Answer: It compiles and prints 23 because the three count declarations have nonoverlapping scopes. Whenever you see a question about variable declarations in Java, think carefully about scope — the region of code where a variable is accessible and, importantly, where its name is "reserved." In Java, a variable declared inside a block (between { and }) exists only within that block. The if block and the else block are separate, non-overlapping scopes. So declaring int count = 1 inside the if block and int count = 2 inside the else block is perfectly legal — neither declaration is visible outside its own block. Once both blocks close, those two count variables are gone entirely, and the compiler has no memory of them. That's why declaring int count = 3 afterward at the method level is also legal — it doesn't conflict with either branch-local variable. Since flag is false, the else branch executes, printing 2, and then the method-level count = 3 prints, giving you 23. Answer A is correct. Answer B is wrong because it assumes the if branch runs despite flag being false — Java evaluates the condition at runtime, not at compile time. Answer C is wrong because there's no rule preventing branch-local variables from being printed inside their own block; System.out.print(count) inside each branch is perfectly valid. Answer D describes a common misconception: many students assume you can't reuse a variable name anywhere in a method, but Java only prohibits declarations in overlapping scopes, not sequential, non-overlapping ones. As a study tip, remember: scope is about block boundaries, not method boundaries. If two blocks don't nest inside each other, they can reuse the same variable name without conflict.
  5. What is the result of compiling and running this program?
    Answer: It compiles and prints LL7 because the loop variable's scope ends with the loop. When you see a question about variable naming in Java, think carefully about variable scope — specifically, where a variable "lives" and when it disappears. In Java, a variable declared inside a for loop header (like int i = 0) is scoped strictly to that loop block. Once the closing brace of the loop is reached, that i simply ceases to exist. This means the int i = 7 declaration afterward is perfectly legal — it's a brand-new variable in the method's scope, with no conflict. The program prints "L" twice during the loop, then prints 7, giving you LL7. Answer A is correct. Answer B is wrong because it assumes the loop variable "survives" and retains its final value (i = 2 after the loop increments past the condition). This would only be true if i were declared outside the loop — but here it's declared inside the loop header, so it's gone the moment the loop ends. Answer C is the most tempting trap. Many students assume that having two local variables named i in the same method always causes a compile error. It doesn't — as long as their scopes don't overlap. Since the loop's i is dead before the second i is declared, there's no naming conflict. Answer D is wrong for the same reason: i = 7 is perfectly visible to the final System.out.print(i) because they're in the same enclosing method scope. Study tip: Always trace variable scope by block — curly braces define the boundary. If the blocks don't overlap, duplicate names are allowed in Java.
  6. What is the result of compiling and running this program?
    Answer: It fails compilation because n is redeclared while the outer local variable remains in scope. When you see a question about variable declarations inside nested blocks, you should immediately think about Java's local variable scoping rules — specifically, whether re-declaring a variable name is permitted. In Java, you cannot declare a local variable in an inner block if a variable with the same name already exists in an enclosing scope within the same method. The key rule is: a local variable's scope begins at its declaration and extends to the end of the block that contains it. Since the outer n is still in scope when the inner block begins, attempting to declare another n inside that block creates a duplicate variable conflict. The compiler treats this as an error, not as shadowing. Therefore, C is correct — the program fails to compile because n is redeclared while the outer local variable is still visible. A describes "shadowing," which is a real concept in Java — but it only applies to instance or class fields, not local variables. If n were a field, an inner local declaration could indeed shadow it. That distinction is exactly the trap this question sets. B extends that same misconception further by suggesting the inner declaration persists after its block, which is doubly wrong — even if it compiled, inner block variables are destroyed when the block exits. D is incorrect because the real issue is the duplicate declaration, not initialization; the inner n is properly initialized to 2 before being printed. A useful rule of thumb: in Java, fields can be shadowed, but local variables cannot be re-declared within the same method scope. Keep that distinction sharp, and you'll catch these compiler-error traps immediately.
  7. What is the result of compiling and running this program?
    Answer: It fails compilation because both value declarations belong to the same switch block. When you see a switch statement in Java, remember that all case labels share a single block scope — the entire body of the switch is one block, not separate blocks per case. This is the core concept being tested here. Because the whole switch body is one scope, declaring int value in case 1 and again in case 2 is like declaring the same variable twice in the same block. Java's compiler sees both declarations as belonging to the same scope and flags it as a duplicate variable declaration — compilation fails. That's why D is correct. A is tempting because it sounds logically reasonable: only case 2 executes at runtime, so why should case 1's declaration matter? But the compiler performs static analysis of scopes before any runtime behavior occurs. It doesn't care which case will actually run — it sees the conflict immediately. B is a subtle misconception. It's actually true that value stays in scope across all cases (since they share one block), but that doesn't save you here — it's precisely because they share scope that the second declaration of value is illegal. B mistakes a real fact for a safe outcome. C describes a legitimate Java error that can happen with local variables — using a variable before initialization — but that's not the issue here. The program never even gets that far; the duplicate declaration prevents compilation entirely. As a study tip: whenever you see variable declarations inside a switch, mentally flatten all the case blocks into one single block. If any variable name appears twice, expect a compilation error.
  8. What is the result of compiling and running this program?
    Answer: It fails compilation because resource variable s is not in scope in the catch block. When you see a question involving try-with-resources, pay close attention to variable scoping rules — specifically where the resource variable is and isn't accessible. In a try-with-resources statement, the resource variable (here, s) is declared inside the resource specification header. According to the Java Language Specification, that variable's scope is limited to the try block body only — it does not extend into the associated catch or finally blocks. This makes intuitive sense: by the time a catch block executes, the resource has already been automatically closed and is conceptually gone. So when the catch block attempts to call s.hasNext(), the compiler sees s as an undeclared identifier in that scope, causing a compilation failure. That confirms B is correct. A is wrong in two ways: even if the logic "no exception occurs, so catch doesn't run" were true at runtime, the program never gets that far — it fails at compile time because s is referenced outside its valid scope. C is a tempting distractor because it sounds similar to B, but it misstates the rule. The resource variable is accessible inside the try block body — it's not limited to just the resource header itself. The restriction is specifically that it doesn't reach catch or finally. D is wrong for the same reason as A: the program doesn't compile at all, so no output is ever produced. A good study tip: memorize the mantra "try-with-resources scope = try block only." Whenever you see a resource variable used in a catch or finally, flag it immediately as a compilation error.
  9. What is the result of compiling and running this program?
    Answer: It compiles and prints 6 after using two distinct variables named step. When you see a question involving repeated variable names in Java, your focus should be on block scope — the rule that a variable only exists within the curly braces {} where it was declared. In this program, step is declared inside two separate, sequential blocks. Each block creates its own isolated scope. The first block declares step = 2 and adds it to total, making total = 2. Once that block closes, step no longer exists. The second block then declares a brand new variable also named step = 3, and multiplies total by it: 2 * 3 = 6. The program prints 6, confirming A is correct — two distinct variables happen to share a name, which is perfectly legal since their scopes never overlap. B is wrong because it misreads the operators — the second block uses *=, not +=. If both were additions, the result would be 5, but Java is precise about operators. C is wrong because it imagines the second step overwrites the first, as if they were the same variable. They're not — the first step is already out of scope before the second is declared, so no replacement occurs. D is the most tempting wrong answer, and it reflects a common misconception. Java does prevent re-declaring a variable in an overlapping scope (like a nested block), but these two blocks are sibling blocks — sequential, not nested. The compiler sees no conflict. Study tip: Watch for questions where the same variable name appears in sibling blocks versus nested blocks — those two situations have very different rules in Java.
  10. What is the result of compiling and running this program?
    Answer: It fails compilation because a lambda parameter cannot redeclare an enclosing local variable. When you see a lambda expression alongside a local variable in the enclosing scope, you should immediately think about Java's variable shadowing rules — specifically, how they differ between lambdas and anonymous classes. In Java, a lambda expression does not introduce a new scope the way an anonymous class or a block does. Instead, it shares the enclosing scope. Because of this, a lambda parameter is treated as a local variable within that same scope. Java explicitly prohibits declaring a variable inside a lambda that has the same name as a variable already in the enclosing method. Here, limit is already declared as a local variable in main, so naming the lambda parameter limit as well is a direct conflict — the compiler rejects it. This makes C the correct answer: the code fails to compile because a lambda parameter cannot redeclare an enclosing local variable. A is wrong because it assumes shadowing is permitted inside lambdas, which is only true for anonymous classes — not lambdas. B is wrong for the same reason; it assumes the lambda runs without issue and that the outer limit remains visible, but the real problem occurs before runtime. D is a red herring — Java lambdas support type inference, so explicit parameter types are completely optional; that rule has nothing to do with this error. As a study tip, remember the key contrast: anonymous classes can shadow outer variables, but lambdas cannot. If you see a lambda parameter name that matches any variable in the enclosing method, expect a compilation error — it's one of Java's most commonly tested lambda scoping rules.

Start this quiz