Java Save Actions Plus
Additional Java save actions for VS Code, designed to complement the built-in Java cleanup support from the Red Hat Java extension.
This extension runs on Java file save and applies extra cleanup rules that are commonly available in STS / Eclipse save actions but are not fully covered by native VS Code Java cleanup options.
What this extension does
When you press Ctrl+S on a Java file, this extension can apply extra cleanup actions such as:
- converting simple
replaceAll() calls to replace()
- converting
.strip().isEmpty() to .isBlank()
- replacing
Boolean.TRUE / Boolean.FALSE with primitive boolean literals in safe cases
- converting wrapper constructor usage to
valueOf()
- removing unnecessary
new String("...")
- converting explicit generic constructor types to the diamond operator
- wrapping single-line
if / for / while statements in braces
- removing unnecessary literal casts
- trimming trailing whitespace
- and other Java save cleanups implemented by the extension
This extension is intended to work alongside the Java extension from Red Hat, not replace it.
How it works
On save of a .java file, the cleanup flow is:
- VS Code / Red Hat Java native save actions run if you have them enabled in
settings.json
- Java Save Actions Plus runs its own additional cleanup rules
- If any rule changes the file, the extension writes the cleaned result back to the editor
So the final save behavior is:
Save Java file → native Java cleanup → extension cleanup rules → final saved file
What is covered by native Java cleanup vs this extension
Native Java cleanup from Red Hat Java
These are examples of cleanup actions that come from the Java extension ecosystem itself when configured in java.cleanup.actionsOnSave:
- Add
@Override
- Add
@Deprecated
- Qualify members with
this
- Qualify static members with the declaring type
- Add
final
- Convert anonymous class to lambda
- Simplify lambda expressions / method references
- Organize imports
- Convert
instanceof patterns
- Convert some switch forms
- Invert equals for null safety
- Other Red Hat / JDT cleanup actions depending on Java version
Additional cleanup rules from this extension
This extension focuses on extra save actions not fully covered by native VS Code Java cleanup.
Current extension rules include:
- Remove unnecessary literal casts
- Convert single-line control statements to blocks
- Use diamond operator
- Convert simple
.replaceAll() to .replace()
- Convert
.strip().isEmpty() to .isBlank()
- Convert eager boolean operators to lazy operators in supported boolean contexts
- Replace
Boolean.TRUE / Boolean.FALSE with primitive literals in safe contexts
- Remove unnecessary
new String("literal")
- Use
valueOf() instead of wrapper constructors
- Remove trailing whitespace
Rule examples
Below are examples of the kinds of transformations this extension performs.
1) Remove unnecessary literal casts
Before
public class Demo {
public void test() {
String value = (String) "hello";
int count = (int) 5;
boolean enabled = (boolean) true;
}
}
After
public class Demo {
public void test() {
String value = "hello";
int count = 5;
boolean enabled = true;
}
}
2) Convert single-line control statements to blocks
Before
public class Demo {
public void test(boolean flag) {
if (flag) System.out.println("yes");
while (flag) System.out.println("loop");
for (int i = 0; i < 3; i++) System.out.println(i);
}
}
After
public class Demo {
public void test(boolean flag) {
if (flag) {
System.out.println("yes");
}
while (flag) {
System.out.println("loop");
}
for (int i = 0; i < 3; i++) {
System.out.println(i);
}
}
}
3) Use diamond operator
Before
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Demo {
public void test() {
List<String> names = new ArrayList<String>();
Map<String, Integer> counts = new HashMap<String, Integer>();
}
}
After
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Demo {
public void test() {
List<String> names = new ArrayList<>();
Map<String, Integer> counts = new HashMap<>();
}
}
4) Convert simple replaceAll() to replace()
This rule only changes cases where the first argument is a plain literal and not a real regex pattern.
Before
public class Demo {
public void test() {
String value = "a-b-c";
value = value.replaceAll("-", "_");
value = value.replaceAll("x", "y");
}
}
After
public class Demo {
public void test() {
String value = "a-b-c";
value = value.replace("-", "_");
value = value.replace("x", "y");
}
}
5) Convert .strip().isEmpty() to .isBlank()
Before
public class Demo {
public boolean test(String input) {
return input.strip().isEmpty();
}
}
After
public class Demo {
public boolean test(String input) {
return input.isBlank();
}
}
This rule assumes a Java version where String.isBlank() is available.
6) Use lazy boolean operators in supported boolean contexts
Before
public class Demo {
public boolean test(boolean a, boolean b) {
return a & b;
}
}
After
public class Demo {
public boolean test(boolean a, boolean b) {
return a && b;
}
}
7) Replace Boolean.TRUE / Boolean.FALSE with primitive literals in safe cases
Before
public class Demo {
public boolean test() {
boolean enabled = Boolean.TRUE;
return Boolean.FALSE;
}
}
After
public class Demo {
public boolean test() {
boolean enabled = true;
return false;
}
}
8) Remove unnecessary new String("...")
Before
public class Demo {
public String test() {
String a = new String("hello");
return new String("world");
}
}
After
public class Demo {
public String test() {
String a = "hello";
return "world";
}
}
9) Use valueOf() instead of wrapper constructors
Before
public class Demo {
public void test() {
Integer a = new Integer(5);
Long b = new Long(10L);
Boolean c = new Boolean(true);
}
}
After
public class Demo {
public void test() {
Integer a = Integer.valueOf(5);
Long b = Long.valueOf(10L);
Boolean c = Boolean.valueOf(true);
}
}
10) Remove trailing whitespace
Trailing spaces and tabs at the end of lines are removed automatically.
How to use it
1. Install the extension
Install Java Save Actions Plus from the VSIX or Marketplace.
2. Make sure you have Java support in VS Code
For best results, also install the Java extension stack, especially the Red Hat Java extension.
3. Open a Java project or Java file
The extension activates for Java files.
4. Save a Java file
Press Ctrl+S on a .java file.
If the extension finds any matching cleanup opportunities, it rewrites the file automatically.
Recommended VS Code settings
Add the following to your settings.json for a good combined setup with native Java cleanup:
{
"[java]": {
"editor.formatOnSave": true
},
"java.cleanup.actionsOnSave": [
"addOverride",
"addDeprecated",
"qualifyMembers",
"qualifyStaticMembers",
"addFinalModifier",
"lambdaExpressionFromAnonymousClass",
"lambdaExpression",
"organizeImports"
],
"kb-java-save-actions.enabled": true,
"kb-java-save-actions.enableCustomRules": true,
"kb-java-save-actions.debounceMs": 300,
"kb-java-save-actions.logLevel": "info"
}
Extension settings
This extension contributes the following settings:
kb-java-save-actions.enabled
Enable or disable the extension save-action pipeline.
Type: boolean
Default: true
kb-java-save-actions.enableCustomRules
Enable or disable the custom cleanup rules from this extension.
Type: boolean
Default: true
kb-java-save-actions.debounceMs
Debounce delay in milliseconds before the cleanup pipeline runs after a save event.
Type: number
Default: 300
kb-java-save-actions.logLevel
Controls extension logging verbosity.
Supported values:
Default: info
Typical use cases
This extension is useful when you want VS Code Java save behavior closer to an STS / Eclipse cleanup workflow.
Examples:
- teams moving from STS / Eclipse to VS Code and wanting more save-action cleanup
- Java projects that want automatic cleanup of common code patterns on save
- developers who already use Red Hat Java cleanup but want additional style cleanup beyond native coverage
- internal Java codebases where consistent save-time cleanup matters
Notes and limitations
- The extension is designed to be conservative. It only changes patterns it considers safe for the implemented rule.
- Some Java cleanups still require deeper type-aware or AST-aware analysis and are not covered by simple text-level rules.
- The extension is meant to complement native Java cleanup, not replace it.
- Results may depend on the exact code shape. Some rules intentionally skip ambiguous cases rather than risk breaking code.
Commands
The extension contributes commands for manual use as well:
- KB Java: Run Save Actions on Active File
- KB Java: Show Output Channel
These are useful when you want to test the cleanup pipeline without waiting for a normal save cycle.
Troubleshooting
Nothing happens on save
Check:
- the file is a
.java file
kb-java-save-actions.enabled is true
kb-java-save-actions.enableCustomRules is true
- the code actually matches one of the implemented cleanup patterns
- the extension is installed in the VS Code instance you are testing
I want more native Java cleanup too
Make sure java.cleanup.actionsOnSave is configured in settings.json and that your Java extension setup is working properly.
I want to see which rules ran
Set:
"kb-java-save-actions.logLevel": "debug"
and then open the extension output channel.
Version
Current release: 1.3.0