Hello! I think this violates the structured programming principles, as it makes the scopes non-nested anymore. This would complicate code understanding and refactoring (like extract method or inline method). Finally, I believe, almost nobody would use this feature because the code works fine without it. I agree with Remi: if you want to restrict the scope, either create a block, or extract a method.
With best regards, Tagir Valeev On Mon, Jan 26, 2026 at 7:32 AM Marek Kozieł <[email protected]> wrote: > Hi, > > Java lacks a way to express intentional end-of-use. > > This leads to: > - accidental reuse of values that are no longer semantically valid > - unclear intent during code review > - refactoring hazards when scopes expand > > I’m interested in revisiting and refining this concept (raw form was > discussed during Project Coin in 2009). The goal is to better understand > the problem space so that, if and when the benefits clearly justify it, a > well-formed direction could be considered. > > > > OVERVIEW > > FEATURE SUMMARY: > The forget keyword prevents further access to a variable, parameter, or > field within a defined scope, attempts to access the variable in forbidden > scope will result in a compile-time error. > > MAJOR ADVANTAGE: > This change makes variable and resource lifetimes explicit and > compiler-enforced, improving code clarity and predictability. > > MAJOR BENEFITS: > Allows explicitly removing a variable from the active context (in terms of > accessibility), which is currently: > > impossible for final variables (only comments can be used), > impossible for method parameters (except assigning null to non-final > references), > impossible for fields, > cumbersome for local variables, requiring artificial blocks (extra lines > and indentation). > > Makes it possible to explicitly declare that a variable should no longer > be used or no longer represents valid data in the current scope, including > cases where continued use would be undesirable or error-prone (like when > there is method created for this purpose). > Preserves code quality over time, avoiding degradation caused by = null > assignments, comments-only conventions, or artificial scoping blocks. > > MAJOR DISADVANTAGE: > The introduction of a new reserved keyword introduces potential source > incompatibilities with existing codebases that define identifiers named > forget. > > ALTERNATIVES: > Java currently provides only scope-based lifetime control (blocks and > try-with-resources). It lacks a general, explicit, and compiler-enforced > mechanism to terminate variable usability at an arbitrary point within an > existing scope. > > EXAMPLES > > Simple and Advanced Examples: > forget var; // Variable is forgotten for the remainder of the current > block or method (default behavior) > forget var : scope; // Variable is forgotten inside the entire scope > statement > > where scope could potentially be : if, for, while, try, label, static, > method > > forget (var1, var2, ...); // Specified variables are forgotten for the > remainder of the current block > > forget this.field; // Specified field are forgotten for the remainder of > the current block > > forget (var1, var2, ...) { /* code */ }; // Specified variables are > forgotten only inside the enclosed block > > void handleRequest(String request, String token) { if > (!isTokenValid(token)) { > throw new SecurityException("Invalid token"); > } > > authorize(request, token); > > forget token /* used & contains sensitive info */; > > process(request); > > logger.debug("token was: " + token); // Compile-time error: 'token' has > been forgotten and cannot be used > } > > public Product(String name) { // constructor > this.name = name.trim().intern(); > forget name; // From now on, only use 'this.name'! > > // other constructor commands... > > if (isDuplicate(this.name)) { ... } // Always canonical, never raw > input > if (isDuplicate(name)) { ... } // Compile-time ERROR! > } > > // * Forces usage of the correctly prepared value (this.name) only. > // * Prevents code drift, maintenance bugs, or copy-paste errors that > reference the raw parameter. > // * Makes the constructor safer: no risk of mismatches or inconsistent > logic. > // * Reads as a contract: "from here on, don't touch the original > argument!" > Next Version Examples: > forget ClassName.field; > forget variable.field; > forget (!variable); // Limit allowed variables to ones that are directly > specified > > DETAILS > > SPECIFICATION: > forget [ Identifier | ( IdentifierList ) ] [ : Scope | { block }]; > > IdentifierList: > Identifier {, Identifier} > > Identifier: > [ VariableIdentifier | this.FieldIdentifier ] > > The forget statement forbids any further use of the specified identifier > in all subsequent expressions and statements within the declared scope in > which the identifier would normally be accessible. > > COMPILATION: > The variable is not physically erased (except it may be if not a field); > rather, it is protected from any further access after the forget statement. > Additionally, retaining the variable in the scope (but inaccessible) > prevents situations where a developer tries to create a new variable with > the same name after removing the forget statement, thereby enforcing > consistent usage and avoiding hidden bugs. > > TESTING: > Testing the forget statement is equivalent to testing variable scope after > exiting a block—the variable becomes inaccessible. For fields, forget > enforces access control, ensuring the field cannot be used within the > specified scope for the remainder of its block or method.LIBRARY > > COMPATIBILITY > The introduction of a new keyword (forget) may cause conflicts in > codebases where forget is already used as an identifier. There are no other > compatibility impacts. > > REFERENCES > Current draft » > https://lasu2string.blogspot.com/2026/01/Java-forget-keyword.html > Reddit discussion » > https://www.reddit.com/r/java/comments/1qhhf9y/proposal_introducing_the_forget_keyword_in_java/ > Draft from 2009 » > https://lasu2string.blogspot.com/2009/03/forget-keyword-proposal_27.html > Project coin 2009 discussion entry » > https://mail.openjdk.org/pipermail/coin-dev/2009-March/001093.html > JDK-6189163 » https://bugs.openjdk.org/browse/JDK-6189163 > > > PROBLEMS > > Backward Compatibility: Introducing forget as a new reserved keyword will > cause compilation errors in existing code that already uses forget as an > identifier (variable, method, class, etc). > Tooling Lag: IDEs, static analysis tools, and debuggers must all be > updated to handle the new keyword and its effects on variable visibility. > Code Readability: Misuse or overuse of forget could make code harder to > maintain or follow if not used judiciously, especially if variables are > forgotten in non-obvious places. > Teaching and Onboarding: This feature introduces a new concept that must > be documented and taught to all developers, which can increase the learning > curve for Java. > Migration Complexity: Automatic migration of legacy code may be > challenging, particularly for projects that rely on forget as an existing > identifier or which have established conventions for variable lifetime. > Interaction with Scoping and Shadowing: The detailed behavior when > variables are forgotten, shadowed, or reintroduced in inner scopes may lead > to confusion and subtle bugs if not carefully specified and implemented. > Reflection and Debugging: While reflective APIs themselves are not > impacted, developers may be surprised by the presence of variables at > runtime (for debugging or reflection) that are "forgotten" in the source > code. > Consistency Across Language Features: Defining consistent behavior for > forget in new contexts (e.g., lambdas, anonymous classes, record classes) > may require extra specification effort. > Edge Cases and Specification Complexity: Fully specifying the semantics of > forget for all cases—including fields, parameters, captured variables in > inner/nested classes, and interaction with try/catch/finally—may be complex. > Unused Feature Risk: There is a risk that the forget keyword will see > little real-world use, or will be misunderstood, if not supported and > encouraged by frameworks or coding standards. > > THE RIGHT AND THE WRONG WAY > > During the discussion, it became clear that the main conception of usage > was not approached from the right angle. > For example, the request JDK-6189163: New language feature: undeclare > operator made a similar suggestion. Unfortunately, much of the focus was on > "destroying" variables as a matter of code complexity and maintenance. This > focus is problematic for several reasons: > > The compiler can already release variables when they are no longer needed. > Focusing on disposing bytes of data is really a bad step as it shouldn't > be a concern in the first place. > Focusing on variable usability in this way actually decreases > maintainability, since both current and future modifications would require > additional checks to unlock variables or identify where a variable has been > "undeclared" in the middle of code. This complicates code changes > unnecessarily. > > > > At the same time, we should highlight that many language features are, to > some extent, syntactic sugar from a usability perspective: > > Block-based local variable scoping > - Enhanced for Loop > - Final guard > - Generics > - Lambdas > - Records > - Switch Expressions > - Text Blocks > - Try-With-Resources > - ... and many more > > Each of these features can absolutely be used in the wrong way, which may > decrease code quality. > On the other hand, when used properly, they can significantly reduce > cognitive load and the time required for analysis, refactoring, and > modification - and this path the change will aim to follow. > > So we should focus on situations where forget is actually beneficial in > the short or long term: > > When code is actively being developed -especially complex one - there are > situations where removing unnecessary variables from the context is > beneficial. It's entirely possible that in the final version these > variables will be placed into proper scopes with no need of forget, but > until then forget would serve an important purpose during development. > When modifying long or complex code—especially if an issue arises from the > incorrect reuse of a variable: We could safeguard the variable with a > comment explaining its intended use and the change made. This targeted fix > is preferable to an unannotated quick fix (which leaves confusion for > future maintainers) or an extensive refactor, which could disrupt code > history and introduce new errors. > Writing security-sensitive code where resources need to be released in a > specific order that cannot be enforced using classic block structures. > Explicitly excluding class variables from the current method scope when > ussage could be harmfull(for example in efficiency aspect), helping to > prevent accidental usage and improve code clarity. > > > > SIMPLIFIED VERSION > > Problem: Handling variable "forgetting" via scope control can introduce > unnecessary complexity. To address this, an alternative version without > scope customization could be considered. > > Simplified Solution: > > Instead of customizing scopes, forget could apply to the method/block > scope. > Caveat: It does NOT work for mutually exclusive scopes like parallel > branches (if-else, switch-case). In those, you must restate forget in each > branch. > > void handleRequest(String request, String token) { > if (!isTokenValid(token)) { > throw new SecurityException("Invalid token"); > } > if (forceLogOut()){ > logOut(request, token); > forget token; // prevent usage in the rest of this block and after > the if-else > ... > } else { > authorize(request, token); > forget token; // 'forget' needs to be restated here > ... > } > logger.debug("token was: " + token); // Compile-time error! > } > This approach is more rigid and resistant to refactoring mistakes if block > scopes change. > If more flexibility is needed, a more complex form like forget var : > label; (for better control) can be introduced as an advanced feature. > > SUMMARY > > The forget keyword represents a natural evolution of Java's commitment to > clear, explicit, and compiler-enforced language rules. By allowing > developers to mark variables, parameters, or fields as no longer usable > within a defined scope, forget makes variable lifetimes and resource > management visible and deliberate. This approach eliminates ambiguity in > code, prevents accidental misuse, and reinforces Java’s tradition of making > correctness and safety a language guarantee, not just a convention. Like > Java’s robust type system and scoping mechanisms, forget enhances code > clarity, maintainability, and reliability. > > -- > Greetings > Marek Kozieł ( Lasu ) >
