public class MagicNumberCheck extends AbstractCheck
Checks that there are no "magic numbers" where a magic number is a numeric literal that is not defined as a constant. By default, -1, 0, 1, and 2 are not considered to be magic numbers.
Constant definition is any variable/field that has 'final' modifier. It is fine to have one constant defining multiple numeric literals within one expression:
static final int SECONDS_PER_DAY = 24 * 60 * 60; static final double SPECIAL_RATIO = 4.0 / 3.0; static final double SPECIAL_SUM = 1 + Math.E; static final double SPECIAL_DIFFERENCE = 4 - Math.PI; static final Border STANDARD_BORDER = BorderFactory.createEmptyBorder(3, 3, 3, 3); static final Integer ANSWER_TO_THE_ULTIMATE_QUESTION_OF_LIFE = new Integer(42);
ignoreNumbers - Specify non-magic numbers.
Type is double[].
Default value is -1, 0, 1, 2.
ignoreHashCodeMethod - Ignore magic numbers in hashCode methods.
Type is boolean.
Default value is false.
ignoreAnnotation - Ignore magic numbers in annotation declarations.
Type is boolean.
Default value is false.
ignoreFieldDeclaration - Ignore magic numbers in field declarations.
Type is boolean.
Default value is false.
ignoreAnnotationElementDefaults -
Ignore magic numbers in annotation elements defaults.
Type is boolean.
Default value is true.
constantWaiverParentToken - Specify tokens that are allowed in the AST path
from the number literal to the enclosing constant definition.
Type is java.lang.String[].
Validation type is tokenTypesSet.
Default value is
TYPECAST,
METHOD_CALL,
EXPR,
ARRAY_INIT,
UNARY_MINUS,
UNARY_PLUS,
ELIST,
STAR,
ASSIGN,
PLUS,
MINUS,
DIV,
LITERAL_NEW.
tokens - tokens to check
Type is java.lang.String[].
Validation type is tokenSet.
Default value is:
NUM_DOUBLE,
NUM_FLOAT,
NUM_INT,
NUM_LONG.
To configure the check with default configuration:
<module name="MagicNumber"/>
results is following violations:
@MyAnnotation(6) // violation
class MyClass {
private field = 7; // violation
void foo() {
int i = i + 1; // no violation
int j = j + 8; // violation
}
public int hashCode() {
return 10; // violation
}
}
@interface anno {
int value() default 10; // no violation
}
To configure the check so that it checks floating-point numbers that are not 0, 0.5, or 1:
<module name="MagicNumber"> <property name="tokens" value="NUM_DOUBLE, NUM_FLOAT"/> <property name="ignoreNumbers" value="0, 0.5, 1"/> <property name="ignoreFieldDeclaration" value="true"/> <property name="ignoreAnnotation" value="true"/> </module>
results is following violations:
@MyAnnotation(6) // no violation
class MyClass {
private field = 7; // no violation
void foo() {
int i = i + 1; // no violation
int j = j + 8; // violation
}
}
To configure the check so that it ignores magic numbers in field declarations:
<module name="MagicNumber"> <property name="ignoreFieldDeclaration" value="false"/> </module>
results in the following violations:
public record MyRecord() {
private static int myInt = 7; // ok, field declaration
void foo() {
int i = myInt + 1; // no violation, 1 is defined as non-magic
int j = myInt + 8; // violation
}
}
To configure the check to check annotation element defaults:
<module name="MagicNumber"> <property name="ignoreAnnotationElementDefaults" value="false"/> </module>
results in following violations:
@interface anno {
int value() default 10; // violation
int[] value2() default {10}; // violation
}
Config example of constantWaiverParentToken option:
<module name="MagicNumber"> <property name="constantWaiverParentToken" value="ASSIGN,ARRAY_INIT,EXPR, UNARY_PLUS, UNARY_MINUS, TYPECAST, ELIST, DIV, PLUS "/> </module>
result is following violation:
class TestMethodCall {
public void method2() {
final TestMethodCall dummyObject = new TestMethodCall(62); //violation
final int a = 3; // ok as waiver is ASSIGN
final int [] b = {4, 5} // ok as waiver is ARRAY_INIT
final int c = -3; // ok as waiver is UNARY_MINUS
final int d = +4; // ok as waiver is UNARY_PLUS
final int e = method(1, 2) // ELIST is there but violation due to METHOD_CALL
final int x = 3 * 4; // violation
final int y = 3 / 4; // ok as waiver is DIV
final int z = 3 + 4; // ok as waiver is PLUS
final int w = 3 - 4; // violation
final int x = (int)(3.4); //ok as waiver is TYPECAST
}
}
Config example of ignoreHashCodeMethod option:
<module name="MagicNumber"> <property name="ignoreHashCodeMethod" value="true"/> </module>
result is no violation:
class TestHashCode {
public int hashCode() {
return 10; // OK
}
}
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
magic.number
AutomaticBean.OutputStreamOptions| Modifier and Type | Field and Description |
|---|---|
private int[] |
constantWaiverParentToken
Specify tokens that are allowed in the AST path from the
number literal to the enclosing constant definition.
|
private boolean |
ignoreAnnotation
Ignore magic numbers in annotation declarations.
|
private boolean |
ignoreAnnotationElementDefaults
Ignore magic numbers in annotation elements defaults.
|
private boolean |
ignoreFieldDeclaration
Ignore magic numbers in field declarations.
|
private boolean |
ignoreHashCodeMethod
Ignore magic numbers in hashCode methods.
|
private double[] |
ignoreNumbers
Specify non-magic numbers.
|
static java.lang.String |
MSG_KEY
A key is pointing to the warning message text in "messages.properties"
file.
|
| Constructor and Description |
|---|
MagicNumberCheck()
Constructor for MagicNumber Check.
|
| Modifier and Type | Method and Description |
|---|---|
private static DetailAST |
findContainingConstantDef(DetailAST ast)
Finds the constant definition that contains aAST.
|
int[] |
getAcceptableTokens()
The configurable token set.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private static boolean |
isChildOf(DetailAST ast,
int type)
Determines if the given AST node has a parent node with given token type code.
|
private static boolean |
isFieldDeclaration(DetailAST ast)
Determines whether or not the given AST is field declaration.
|
private static boolean |
isInHashCodeMethod(DetailAST ast)
Determines whether or not the given AST is in a valid hash code method.
|
private boolean |
isInIgnoreList(DetailAST ast)
Decides whether the number of an AST is in the ignore list of this
check.
|
private boolean |
isMagicNumberExists(DetailAST ast,
DetailAST constantDefAST)
Is magic number some where at ast tree.
|
private void |
reportMagicNumber(DetailAST ast)
Reports aAST as a magic number, includes unary operators as needed.
|
void |
setConstantWaiverParentToken(java.lang.String... tokens)
Setter to specify tokens that are allowed in the AST path from the
number literal to the enclosing constant definition.
|
void |
setIgnoreAnnotation(boolean ignoreAnnotation)
Setter to ignore magic numbers in annotation declarations.
|
void |
setIgnoreAnnotationElementDefaults(boolean ignoreAnnotationElementDefaults)
Setter to ignore magic numbers in annotation elements defaults.
|
void |
setIgnoreFieldDeclaration(boolean ignoreFieldDeclaration)
Setter to ignore magic numbers in field declarations.
|
void |
setIgnoreHashCodeMethod(boolean ignoreHashCodeMethod)
Setter to ignore magic numbers in hashCode methods.
|
void |
setIgnoreNumbers(double... list)
Setter to specify non-magic numbers.
|
private boolean |
shouldTestAnnotationArgs(DetailAST ast)
Checks if ast is annotation argument and should be checked.
|
private boolean |
shouldTestAnnotationDefaults(DetailAST ast)
Checks if ast is annotation element default value and should be checked.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
beginTree, clearViolations, destroy, finishTree, getFileContents, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, isCommentNodesRequired, leaveToken, log, log, log, setFileContents, setTabWidth, setTokensfinishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverityconfigure, contextualize, getConfiguration, setupChildpublic static final java.lang.String MSG_KEY
private int[] constantWaiverParentToken
private double[] ignoreNumbers
private boolean ignoreHashCodeMethod
private boolean ignoreAnnotation
private boolean ignoreFieldDeclaration
private boolean ignoreAnnotationElementDefaults
public MagicNumberCheck()
public int[] getDefaultTokens()
AbstractCheckgetDefaultTokens in class AbstractCheckTokenTypespublic int[] getAcceptableTokens()
AbstractCheckgetAcceptableTokens in class AbstractCheckTokenTypespublic int[] getRequiredTokens()
AbstractCheckgetRequiredTokens in class AbstractCheckTokenTypespublic void visitToken(DetailAST ast)
AbstractCheckvisitToken in class AbstractCheckast - the token to processprivate boolean shouldTestAnnotationArgs(DetailAST ast)
ast - token to checkprivate boolean shouldTestAnnotationDefaults(DetailAST ast)
ast - token to checkprivate boolean isMagicNumberExists(DetailAST ast, DetailAST constantDefAST)
ast - ast tokenconstantDefAST - constant astprivate static DetailAST findContainingConstantDef(DetailAST ast)
ast - the ASTprivate void reportMagicNumber(DetailAST ast)
ast - the AST node that contains the number to reportprivate static boolean isInHashCodeMethod(DetailAST ast)
public int hashCode().ast - the AST from which to search for an enclosing hash code
method definitiontrue if ast is in the scope of a valid hash code method.private boolean isInIgnoreList(DetailAST ast)
ast - the AST to checkprivate static boolean isFieldDeclaration(DetailAST ast)
ast - AST from which to search for an enclosing field declarationtrue if ast is in the scope of field declarationpublic void setConstantWaiverParentToken(java.lang.String... tokens)
tokens - The string representation of the tokens interested inpublic void setIgnoreNumbers(double... list)
list - list of numbers to ignore.public void setIgnoreHashCodeMethod(boolean ignoreHashCodeMethod)
ignoreHashCodeMethod - decide whether to ignore
hash code methodspublic void setIgnoreAnnotation(boolean ignoreAnnotation)
ignoreAnnotation - decide whether to ignore annotationspublic void setIgnoreFieldDeclaration(boolean ignoreFieldDeclaration)
ignoreFieldDeclaration - decide whether to ignore magic numbers
in field declarationpublic void setIgnoreAnnotationElementDefaults(boolean ignoreAnnotationElementDefaults)
ignoreAnnotationElementDefaults - decide whether to ignore annotation elements defaultsprivate static boolean isChildOf(DetailAST ast, int type)
ast - the AST from which to search for annotationstype - the type code of parent tokentrue if the AST node has a parent with given token type.Copyright © 2001-2022. All Rights Reserved.