UnusedLocalVariable

Since Checkstyle 9.3

Description

Checks that a local variable is declared and/or assigned, but not used. Supports pattern variables. Doesn't check array components as array components are classified as different kind of variables by JLS.

Properties

name description type default value since
allowUnnamedVariables Allow variables named with a single underscore (known as unnamed variables in Java 21+). boolean true 10.18.0

Examples

To configure the check:


<module name="Checker">
  <module name="TreeWalker">
    <module name="UnusedLocalVariable">
    </module>
  </module>
</module>

Example:


public class Example1 {
  {
    int k = 12; // violation, assign and update but never use 'k'
    k++;
  }

  int a;
  Example1(int a) { // ok, as 'a' is a constructor parameter not a local variable
    this.a = 12;
  }

  void method(int b) {
    int[] arr = {1, 2, 3};  // violation, unused named local variable 'arr'
    int[] anotherArr = {1}; // ok, 'anotherArr' is accessed
    anotherArr[0] = 4;
  }

  String convertValue(String newValue) {
    String s = newValue.toLowerCase(); // violation, unused named local variable 's'
    String _ = newValue.toLowerCase(); // ok, '_' is unnamed variable
    return newValue.toLowerCase();
  }

  void read() throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s; // violation, unused named local variable 's'
    while ((s = reader.readLine()) != null) {}
    try (BufferedReader reader1 = // ok, 'reader1' is a resource
                 new BufferedReader(new FileReader("abc.txt"))) {}
    try {
    } catch (Exception e) { }  // ok, 'e' is an exception parameter
  }

  void loops() {
    int j = 12;
    for (int i = 0; j < 11; i++)  // violation, unused named local variable 'i'
      for (int p = 0; j < 11; p++) p /= 2;    // ok, 'p' is used
    for (Integer _ : new  int[0]) { } // ok, '_' is unnamed variable
  }

  void lambdas() {
    Predicate<String> obj = (String str) -> true; // ok, 'str' is a lambda parameter
    obj.test("Test");
  }
}

To configure the check to violate variables named with a single underscore if they are not used:


<module name="Checker">
  <module name="TreeWalker">
    <module name="UnusedLocalVariable">
        <property name="allowUnnamedVariables" value="false"/>
    </module>
  </module>
</module>

Example:


public class Example2 {
  {
    int k = 12; // violation, assign and update but never use 'k'
    k++;
  }

  int a;
  Example2(int a) { // ok, as 'a' is a constructor parameter not a local variable
    this.a = 12;
  }

  void method(int b) {
    int[] arr = {1, 2, 3};  // violation, unused local variable 'arr'
    int[] anotherArr = {1}; // ok, 'anotherArr' is accessed
    anotherArr[0] = 4;
  }

  String convertValue(String newValue) {
    String s = newValue.toLowerCase(); // violation, unused local variable 's'
    String _ = newValue.toLowerCase(); // violation, unused local variable '_'
    return newValue.toLowerCase();
  }

  void read() throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s; // violation, unused local variable 's'
    while ((s = reader.readLine()) != null) {}
    try (BufferedReader reader1 = // ok, 'reader1' is a resource
                 new BufferedReader(new FileReader("abc.txt"))) {}
    try {
    } catch (Exception e) { }  // ok, 'e' is an exception parameter
  }

  void loops() {
    int j = 12;
    for (int i = 0; j < 11; i++)  // violation, unused local variable 'i'
      for (int p = 0; j < 11; p++) p /= 2;   // ok, 'p' is used
    for (Integer _ : new  int[0]) { } // violation, unused local variable '_'
  }

  void lambdas() {
    Predicate<String> obj = (String str) -> true; // ok, 'str' is a lambda parameter
    obj.test("Test");
  }
}

Example with pattern variable:


<module name="Checker">
  <module name="TreeWalker">
    <module name="UnusedLocalVariable">
    </module>
  </module>
</module>

Example:


public class Example3 {
  sealed abstract static class Shape permits Circle, Rect {}
  static final class Circle extends Shape {}
  static final class Rect extends Shape {}
  void patternVariables(Object obj, Shape s) {
    if (obj instanceof String str) {
    } // violation above, unused named local variable 'str'
    if (obj instanceof String t) { // ok, 't' is used
      System.out.println(t);
    }
    if (obj instanceof String _) { // ok, '_' is unnamed variable
      System.out.println("string");
    }
    switch (s) { // violation below, unused named local variable 'c'
      case Circle c -> System.out.println("circle");
      case Rect r   -> System.out.println(r); // ok, 'r' is used
      default       -> { }
    }
  }
}

Example:


<module name="Checker">
  <module name="TreeWalker">
    <module name="UnusedLocalVariable">
        <property name="allowUnnamedVariables" value="false"/>
    </module>
  </module>
</module>

Example:


public class Example4 {
  sealed abstract static class Shape permits Circle, Rect {}
  static final class Circle extends Shape {}
  static final class Rect extends Shape {}
  void patternVariables(Object obj, Shape s) {
    if (obj instanceof String str) { // violation, unused local variable 'str'
      System.out.println("string");
    }
    if (obj instanceof String t) { // ok, 't' is used
      System.out.println(t);
    }
    if (obj instanceof String _) { // ok, pattern variable '_' is always skipped
      System.out.println("string");
    }
    switch (s) { // violation below, unused local variable 'c'
      case Circle c -> System.out.println("circle");
      case Rect r   -> System.out.println(r); // ok, 'r' is used
      default       -> { }
    }
  }
}

Example of Usage

Violation Messages

All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.

Fully Qualified Name

com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck

Use this fully qualified class name in configuration when an exact class reference is required.

Parent Module

TreeWalker