The Apex compiler introduced in API Version 42.0 enforces stricter code validation rules, including the detection of unreachable statements and the prevention of mutation of final variables.
In previous versions of the Apex compiler, certain code patterns were allowed even though they contained logical errors — such as incrementing a variable declared as final, or placing executable statements after an unconditional throw statement. These patterns compiled without errors in older API versions.
Starting with API Version 42.0, the Apex compiler correctly identifies and rejects these patterns at compile time. If your Apex class is saved with API Version 42 or higher and contains such code, it will fail to compile with an "Unreachable statement" or similar compile-time error. The purpose of this change is to deprecate a known Apex language bug and improve code quality.
Example of code that no longer compiles in API Version 42.0+:
A variable declared as final integer followed by an increment operation (x++) will produce a compile error because final variables should never be mutated after initialization.
Sample Apex code:
final integer x; x++; // no longer compiles since finals should never mutate
Old behavior (pre-API Version 42.0):
The old Apex compiler allowed dead code — that is, code that could never be reached at runtime — to compile without error. For example, a method that throws an exception followed by a call to another method would compile even though the second method call is unreachable. The old compiler also allowed mutation of final variables.
void m() {
throw new MyException();
doSomething();
}
New behavior (API Version 42.0 and later):
The new compiler rejects unreachable statements and mutations of final variables. Code placed after an unconditional throw statement is flagged as unreachable and the class will not compile.
void m() {
if (true) {
throw new MyException();
}
doSomething();
}
To resolve the "Unreachable statement" compile error, use one of the following approaches:
Option 1 — Remove the dead code:
Review the method and remove any statements that can never be reached. This is the recommended approach as it improves code clarity and maintainability.
Option 2 — Use a conditional wrapper (compatibility workaround):
If removing the dead code is not immediately possible, wrap the throw statement in a conditional block such as if (true) { throw new MyException(); }, followed by the originally unreachable statement. This satisfies the new compiler's reachability analysis while preserving the intended logic. Note: This is a workaround for backward compatibility — the best practice is to refactor the code to remove dead code paths entirely.
For final variable mutation errors:
Remove any operations that mutate a final variable after its declaration. A final variable should be assigned only once at the point of declaration. If the variable value needs to change, remove the final keyword.
000382469

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.