MutableException
Since Checkstyle 3.2
Description
The current algorithm is very simple: it checks that all members of
exception are final. The user can still mutate an exception's instance
(e.g. Throwable has a method called setStackTrace
which changes the exception's stack trace). But, at least, all information
provided by this exception type is unchangeable.
Rationale: Exception instances should represent an error condition. Having non-final fields not only allows the state to be modified by accident and therefore mask the original condition but also allows developers to accidentally forget to set the initial state. In both cases, code catching the exception could draw incorrect conclusions based on the state.
Properties
Examples
To configure the check:
<module name="Checker">
<module name="TreeWalker">
<module name="MutableException"/>
</module>
</module>
Example:
class Example1 extends Exception {
private int code; // OK, class name doesn't match with default pattern
public Example1() {
code = 1;
}
}
class FirstException extends Exception {
private int code; // violation
public FirstException() {
code = 2;
}
}
class FirstThrowable extends Throwable {
final int code; // OK
String message; // violation
public FirstThrowable(int code, String message) {
this.code = code;
this.message = message;
}
}
class FirstBadException extends java.lang.Exception {
int code; // violation
public FirstBadException(int code) {
this.code = code;
}
}
To configure the check so that it checks for class name that ends with 'Exception':
<module name="Checker">
<module name="TreeWalker">
<module name="MutableException">
<property name="format" value="^.*Exception$"/>
</module>
</module>
</module>
Example:
class Example2 extends Exception {
private int code; // OK, class name doesn't match with given pattern
public Example2() {
code = 1;
}
}
class SecondException extends Exception {
private int code; // violation
public SecondException() {
code = 2;
}
}
class SecondThrowable extends Throwable {
final int code; // OK, class name doesn't match with given pattern
String message; // OK, class name doesn't match with given pattern
public SecondThrowable(int code, String message) {
this.code = code;
this.message = message;
}
}
class SecondBadException extends java.lang.Exception {
int code; // violation
public SecondBadException(int code) {
this.code = code;
}
}
To configure the check so that it checks for type name that is used in 'extends' and ends with 'Throwable':
<module name="Checker">
<module name="TreeWalker">
<module name="MutableException">
<property name="extendedClassNameFormat" value="^.*Throwable$"/>
</module>
</module>
</module>
Example:
class Example3 extends Exception {
private int code; // OK, extended class name doesn't match with given pattern
public Example3() {
code = 1;
}
}
class ThirdException extends Exception {
private int code; // OK, extended class name doesn't match with given pattern
public ThirdException() {
code = 2;
}
}
class ThirdThrowable extends Throwable {
final int code; // OK
String message; // violation
public ThirdThrowable(int code, String message) {
this.code = code;
this.message = message;
}
}
class ThirdBadException extends java.lang.Exception {
int code; // OK, extended class name doesn't match with given pattern
public ThirdBadException(int code) {
this.code = code;
}
}
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.
Package
com.puppycrawl.tools.checkstyle.checks.design