public class VisibilityModifierCheck extends AbstractCheck
Checks visibility of class members. Only static final, immutable or annotated
by specified annotation members may be public;
other class members must be private unless the property protectedAllowed
or packageAllowed is set.
Public members are not flagged if the name matches the public
member regular expression (contains "^serialVersionUID$" by
default).
Note that Checkstyle 2 used to include "^f[A-Z][a-zA-Z0-9]*$" in the default pattern
to allow names used in container-managed persistence for Enterprise JavaBeans (EJB) 1.1 with
the default settings. With EJB 2.0 it is no longer necessary to have public access for
persistent fields, so the default has been changed.
Rationale: Enforce encapsulation.
Check also has options making it less strict:
ignoreAnnotationCanonicalNames- the list of annotations which ignore variables in consideration. If user will provide short annotation name that type will match to any named the same type without consideration of package.
allowPublicFinalFields- which allows public final fields.
allowPublicImmutableFields- which allows immutable fields to be declared as public if defined in final class.
Field is known to be immutable if:
Classes known to be immutable are listed in immutableClassCanonicalNames by their canonical names.
Property Rationale: Forcing all fields of class to have private modifier by default is good in most cases, but in some cases it drawbacks in too much boilerplate get/set code. One of such cases are immutable classes.
Restriction: Check doesn't check if class is immutable, there's no checking if accessory methods are missing and all fields are immutable, we only check if current field is immutable or final. Under the flag allowPublicImmutableFields, the enclosing class must also be final, to encourage immutability. Under the flag allowPublicFinalFields, the final modifier on the enclosing class is optional.
Star imports are out of scope of this Check. So if one of type imported via star import collides with user specified one by its short name - there won't be Check's violation.
packageAllowed - Control whether package visible members are allowed.
Type is boolean.
Default value is false.
protectedAllowed - Control whether protected members are allowed.
Type is boolean.
Default value is false.
publicMemberPattern - Specify pattern for public members that should be ignored.
Type is java.util.regex.Pattern.
Default value is "^serialVersionUID$".
allowPublicFinalFields - Allow final fields to be declared as public.
Type is boolean.
Default value is false.
allowPublicImmutableFields - Allow immutable fields to be
declared as public if defined in final class.
Type is boolean.
Default value is false.
immutableClassCanonicalNames - Specify immutable classes canonical names.
Type is java.lang.String[].
Default value is java.io.File, java.lang.Boolean, java.lang.Byte,
java.lang.Character, java.lang.Double, java.lang.Float, java.lang.Integer,
java.lang.Long, java.lang.Short, java.lang.StackTraceElement, java.lang.String,
java.math.BigDecimal, java.math.BigInteger, java.net.Inet4Address, java.net.Inet6Address,
java.net.InetSocketAddress, java.net.URI, java.net.URL, java.util.Locale, java.util.UUID.
ignoreAnnotationCanonicalNames - Specify the list of annotations canonical
names which ignore variables in consideration.
Type is java.lang.String[].
Default value is com.google.common.annotations.VisibleForTesting,
org.junit.ClassRule, org.junit.Rule.
To configure the check:
<module name="VisibilityModifier"/>
To configure the check so that it allows package visible members:
<module name="VisibilityModifier"> <property name="packageAllowed" value="true"/> </module>
To configure the check so that it allows no public members:
<module name="VisibilityModifier"> <property name="publicMemberPattern" value="^$"/> </module>
To configure the Check so that it allows public immutable fields (mostly for immutable classes):
<module name="VisibilityModifier"> <property name="allowPublicImmutableFields" value="true"/> </module>
Example of allowed public immutable fields:
public class ImmutableClass
{
public final ImmutableSet<String> includes; // No warning
public final ImmutableSet<String> excludes; // No warning
public final java.lang.String notes; // No warning
public final BigDecimal value; // No warning
public ImmutableClass(Collection<String> includes, Collection<String> excludes,
BigDecimal value, String notes)
{
this.includes = ImmutableSet.copyOf(includes);
this.excludes = ImmutableSet.copyOf(excludes);
this.value = value;
this.notes = notes;
}
}
To configure the Check in order to allow user specified immutable class names:
<module name="VisibilityModifier"> <property name="allowPublicImmutableFields" value="true"/> <property name="immutableClassCanonicalNames" value=" com.google.common.collect.ImmutableSet"/> </module>
Example of allowed public immutable fields:
public class ImmutableClass
{
public final ImmutableSet<String> includes; // No warning
public final ImmutableSet<String> excludes; // No warning
public final java.lang.String notes; // Warning here because
//'java.lang.String' wasn't specified as allowed class
public final int someValue; // No warning
public ImmutableClass(Collection<String> includes, Collection<String> excludes,
String notes, int someValue)
{
this.includes = ImmutableSet.copyOf(includes);
this.excludes = ImmutableSet.copyOf(excludes);
this.value = value;
this.notes = notes;
this.someValue = someValue;
}
}
Note, if allowPublicImmutableFields is set to true, the check will also check whether generic type parameters are immutable. If at least one generic type parameter is mutable, there will be a violation.
<module name="VisibilityModifier">
<property name="allowPublicImmutableFields" value="true"/>
<property name="immutableClassCanonicalNames"
value="com.google.common.collect.ImmutableSet, com.google.common.collect.ImmutableMap,
java.lang.String"/>
</module>
Example of how the check works:
public final class Test {
public final String s;
public final ImmutableSet<String> names;
public final ImmutableSet<Object> objects; // violation (Object class is mutable)
public final ImmutableMap<String, Object> links; // violation (Object class is mutable)
public Test() {
s = "Hello!";
names = ImmutableSet.of();
objects = ImmutableSet.of();
links = ImmutableMap.of();
}
}
To configure the Check passing fields annotated with @com.annotation.CustomAnnotation:
<module name="VisibilityModifier"> <property name="ignoreAnnotationCanonicalNames" value= "com.annotation.CustomAnnotation"/> </module>
Example of allowed field:
class SomeClass
{
@com.annotation.CustomAnnotation
String annotatedString; // no warning
@CustomAnnotation
String shortCustomAnnotated; // no warning
}
To configure the Check passing fields annotated with @org.junit.Rule, @org.junit.ClassRule and @com.google.common.annotations.VisibleForTesting annotations:
<module name="VisibilityModifier"/>
Example of allowed fields:
class SomeClass
{
@org.junit.Rule
public TemporaryFolder publicJUnitRule = new TemporaryFolder(); // no warning
@org.junit.ClassRule
public static TemporaryFolder publicJUnitClassRule = new TemporaryFolder(); // no warning
@com.google.common.annotations.VisibleForTesting
public String testString = ""; // no warning
}
To configure the Check passing fields annotated with short annotation name:
<module name="VisibilityModifier"> <property name="ignoreAnnotationCanonicalNames" value="CustomAnnotation"/> </module>
Example of allowed fields:
class SomeClass
{
@CustomAnnotation
String customAnnotated; // no warning
@com.annotation.CustomAnnotation
String customAnnotated1; // no warning
@mypackage.annotation.CustomAnnotation
String customAnnotatedAnotherPackage; // another package but short name matches
// so no violation
}
To understand the difference between allowPublicImmutableFields and allowPublicFinalFields options, please, study the following examples.
1) To configure the check to use only 'allowPublicImmutableFields' option:
<module name="VisibilityModifier"> <property name="allowPublicImmutableFields" value="true"/> </module>
Code example:
public class InputPublicImmutable {
public final int someIntValue; // violation
public final ImmutableSet<String> includes; // violation
public final java.lang.String notes; // violation
public final BigDecimal value; // violation
public final List list; // violation
public InputPublicImmutable(Collection<String> includes,
BigDecimal value, String notes, int someValue, List l) {
this.includes = ImmutableSet.copyOf(includes);
this.value = value;
this.notes = notes;
this.someIntValue = someValue;
this.list = l;
}
}
2) To configure the check to use only 'allowPublicFinalFields' option:
<module name="VisibilityModifier"> <property name="allowPublicFinalFields" value="true"/> </module>
Code example:
public class InputPublicImmutable {
public final int someIntValue;
public final ImmutableSet<String> includes;
public final java.lang.String notes;
public final BigDecimal value;
public final List list;
public InputPublicImmutable(Collection<String> includes,
BigDecimal value, String notes, int someValue, List l) {
this.includes = ImmutableSet.copyOf(includes);
this.value = value;
this.notes = notes;
this.someIntValue = someValue;
this.list = l;
}
}
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
variable.notPrivate
AutomaticBean.OutputStreamOptions| Modifier and Type | Field and Description |
|---|---|
private boolean |
allowPublicFinalFields
Allow final fields to be declared as public.
|
private boolean |
allowPublicImmutableFields
Allow immutable fields to be declared as public if defined in final class.
|
private static java.util.List<java.lang.String> |
DEFAULT_IGNORE_ANNOTATIONS
Default ignore annotations canonical names.
|
private static java.util.List<java.lang.String> |
DEFAULT_IMMUTABLE_TYPES
Default immutable types canonical names.
|
private static java.lang.String[] |
EXPLICIT_MODS
Contains explicit access modifiers.
|
private static java.lang.String |
FINAL_KEYWORD
Name for 'final' keyword.
|
private java.util.List<java.lang.String> |
ignoreAnnotationCanonicalNames
Specify the list of annotations canonical names which ignore variables in
consideration.
|
private java.util.List<java.lang.String> |
ignoreAnnotationShortNames
List of ignore annotations short names.
|
private java.util.List<java.lang.String> |
immutableClassCanonicalNames
Specify immutable classes canonical names.
|
private java.util.List<java.lang.String> |
immutableClassShortNames
List of immutable classes short names.
|
static java.lang.String |
MSG_KEY
A key is pointing to the warning message text in "messages.properties"
file.
|
private static java.lang.String |
PACKAGE_ACCESS_MODIFIER
Name for implicit 'package' access modifier.
|
private boolean |
packageAllowed
Control whether package visible members are allowed.
|
private static java.lang.String |
PRIVATE_ACCESS_MODIFIER
Name for 'private' access modifier.
|
private static java.lang.String |
PROTECTED_ACCESS_MODIFIER
Name for 'protected' access modifier.
|
private boolean |
protectedAllowed
Control whether protected members are allowed.
|
private static java.lang.String |
PUBLIC_ACCESS_MODIFIER
Name for 'public' access modifier.
|
private java.util.regex.Pattern |
publicMemberPattern
Specify pattern for public members that should be ignored.
|
private static java.lang.String |
STATIC_KEYWORD
Name for 'static' keyword.
|
| Constructor and Description |
|---|
VisibilityModifierCheck() |
| Modifier and Type | Method and Description |
|---|---|
private boolean |
areImmutableTypeArguments(java.util.List<java.lang.String> typeArgsClassNames)
Checks whether all of generic type arguments are immutable.
|
void |
beginTree(DetailAST rootAst)
Called before the starting to process a tree.
|
private DetailAST |
findMatchingAnnotation(DetailAST variableDef)
Checks whether the AST is annotated with
an annotation containing the passed in regular
expression and return the AST representing that
annotation.
|
int[] |
getAcceptableTokens()
The configurable token set.
|
private static java.lang.String |
getCanonicalName(DetailAST type)
Gets canonical type's name from given
TYPE node. |
private static java.lang.String |
getClassShortName(java.lang.String canonicalClassName)
Gets the short class name from given canonical name.
|
private static java.util.List<java.lang.String> |
getClassShortNames(java.util.List<java.lang.String> canonicalClassNames)
Gets the list with short names classes.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private static DetailAST |
getGenericTypeArgs(DetailAST type,
boolean isCanonicalName)
Returns generic type arguments token.
|
private static java.util.Set<java.lang.String> |
getModifiers(DetailAST defAST)
Returns the set of modifier Strings for a VARIABLE_DEF or CLASS_DEF AST.
|
private static DetailAST |
getNextSubTreeNode(DetailAST currentNodeAst,
DetailAST subTreeRootAst)
Gets the next node of a syntactical tree (child of a current node or
sibling of a current node, or sibling of a parent of a current node).
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private static java.util.List<java.lang.String> |
getTypeArgsClassNames(DetailAST typeArgs)
Returns a list of type parameters class names.
|
private static java.lang.String |
getTypeName(DetailAST type,
boolean isCanonicalName)
Gets the name of type from given ast
TYPE node. |
private static java.lang.String |
getVisibilityScope(DetailAST variableDef)
Returns the visibility scope for the variable.
|
private boolean |
hasIgnoreAnnotation(DetailAST variableDef)
Checks if variable def has ignore annotation.
|
private boolean |
hasProperAccessModifier(DetailAST variableDef,
java.lang.String variableName)
Checks if current variable has proper access modifier according to Check's options.
|
private boolean |
isAllowedPublicField(DetailAST variableDef)
Checks whether the variable satisfies the public field check.
|
private static boolean |
isAnonymousClassVariable(DetailAST variableDef)
Checks if current variable definition is definition of an anonymous class.
|
private static boolean |
isCanonicalName(DetailAST type)
Checks whether type definition is in canonical form.
|
private static boolean |
isFinalField(DetailAST variableDef)
Checks whether current field is final.
|
private boolean |
isIgnoredPublicMember(java.lang.String variableName,
java.lang.String variableScope)
Checks whether variable belongs to public members that should be ignored.
|
private boolean |
isImmutableField(DetailAST variableDef)
Checks if current field is immutable:
has final modifier and either a primitive type or instance of class
known to be immutable (such as String, ImmutableCollection from Guava and etc).
|
private boolean |
isImmutableFieldDefinedInFinalClass(DetailAST variableDef)
Checks whether immutable field is defined in final class.
|
private static boolean |
isPrimitive(DetailAST type)
Checks if current type is primitive type (int, short, float, boolean, double, etc.).
|
private static boolean |
isStarImport(DetailAST importAst)
Checks if current import is star import.
|
private static boolean |
isStaticFinalVariable(DetailAST variableDef)
Checks whether variable has static final modifiers.
|
void |
setAllowPublicFinalFields(boolean allow)
Setter to allow final fields to be declared as public.
|
void |
setAllowPublicImmutableFields(boolean allow)
Setter to allow immutable fields to be declared as public if defined in final class.
|
void |
setIgnoreAnnotationCanonicalNames(java.lang.String... annotationNames)
Setter to specify the list of annotations canonical names which ignore variables
in consideration.
|
void |
setImmutableClassCanonicalNames(java.lang.String... classNames)
Setter to specify immutable classes canonical names.
|
void |
setPackageAllowed(boolean packageAllowed)
Setter to control whether package visible members are allowed.
|
void |
setProtectedAllowed(boolean protectedAllowed)
Setter to control whether protected members are allowed.
|
void |
setPublicMemberPattern(java.util.regex.Pattern pattern)
Setter to specify pattern for public members that should be ignored.
|
private void |
visitImport(DetailAST importAst)
Checks imported type.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
private void |
visitVariableDef(DetailAST variableDef)
Checks access modifier of given variable.
|
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 static final java.util.List<java.lang.String> DEFAULT_IMMUTABLE_TYPES
private static final java.util.List<java.lang.String> DEFAULT_IGNORE_ANNOTATIONS
private static final java.lang.String PUBLIC_ACCESS_MODIFIER
private static final java.lang.String PRIVATE_ACCESS_MODIFIER
private static final java.lang.String PROTECTED_ACCESS_MODIFIER
private static final java.lang.String PACKAGE_ACCESS_MODIFIER
private static final java.lang.String STATIC_KEYWORD
private static final java.lang.String FINAL_KEYWORD
private static final java.lang.String[] EXPLICIT_MODS
private java.util.regex.Pattern publicMemberPattern
private final java.util.List<java.lang.String> ignoreAnnotationShortNames
private final java.util.List<java.lang.String> immutableClassShortNames
private java.util.List<java.lang.String> ignoreAnnotationCanonicalNames
private boolean protectedAllowed
private boolean packageAllowed
private boolean allowPublicImmutableFields
private boolean allowPublicFinalFields
private java.util.List<java.lang.String> immutableClassCanonicalNames
public VisibilityModifierCheck()
public void setIgnoreAnnotationCanonicalNames(java.lang.String... annotationNames)
annotationNames - array of ignore annotations canonical names.public void setProtectedAllowed(boolean protectedAllowed)
protectedAllowed - whether protected members are allowedpublic void setPackageAllowed(boolean packageAllowed)
packageAllowed - whether package visible members are allowedpublic void setPublicMemberPattern(java.util.regex.Pattern pattern)
pattern - pattern for public members to ignore.public void setAllowPublicImmutableFields(boolean allow)
allow - user's value.public void setAllowPublicFinalFields(boolean allow)
allow - user's value.public void setImmutableClassCanonicalNames(java.lang.String... classNames)
classNames - array of immutable types canonical names.public int[] getDefaultTokens()
AbstractCheckgetDefaultTokens in class AbstractCheckTokenTypespublic int[] getAcceptableTokens()
AbstractCheckgetAcceptableTokens in class AbstractCheckTokenTypespublic int[] getRequiredTokens()
AbstractCheckgetRequiredTokens in class AbstractCheckTokenTypespublic void beginTree(DetailAST rootAst)
AbstractCheckbeginTree in class AbstractCheckrootAst - the root of the treepublic void visitToken(DetailAST ast)
AbstractCheckvisitToken in class AbstractCheckast - the token to processprivate static boolean isAnonymousClassVariable(DetailAST variableDef)
variableDef - VARIABLE_DEFprivate void visitVariableDef(DetailAST variableDef)
variableDef - variable to check.private boolean hasIgnoreAnnotation(DetailAST variableDef)
variableDef - VARIABLE_DEFprivate void visitImport(DetailAST importAst)
importAst - Importprivate static boolean isStarImport(DetailAST importAst)
import java.util.*;
importAst - Importprivate boolean hasProperAccessModifier(DetailAST variableDef, java.lang.String variableName)
variableDef - Variable definition node.variableName - Variable's name.private static boolean isStaticFinalVariable(DetailAST variableDef)
variableDef - Variable definition node.private boolean isIgnoredPublicMember(java.lang.String variableName, java.lang.String variableScope)
variableName - Variable's name.variableScope - Variable's scope.private boolean isAllowedPublicField(DetailAST variableDef)
variableDef - Variable definition node.private boolean isImmutableFieldDefinedInFinalClass(DetailAST variableDef)
variableDef - Variable definition node.private static java.util.Set<java.lang.String> getModifiers(DetailAST defAST)
defAST - AST for a variable or class definition.private static java.lang.String getVisibilityScope(DetailAST variableDef)
variableDef - Variable definition node.private boolean isImmutableField(DetailAST variableDef)
immutableClassCanonicalNamesvariableDef - Field in consideration.private static boolean isCanonicalName(DetailAST type)
type - type definition token.private static DetailAST getGenericTypeArgs(DetailAST type, boolean isCanonicalName)
type - type token.isCanonicalName - whether type name is in canonical form.private static java.util.List<java.lang.String> getTypeArgsClassNames(DetailAST typeArgs)
typeArgs - type arguments token.private boolean areImmutableTypeArguments(java.util.List<java.lang.String> typeArgsClassNames)
typeArgsClassNames - type arguments class names.private static boolean isFinalField(DetailAST variableDef)
variableDef - field in consideration.private static java.lang.String getTypeName(DetailAST type, boolean isCanonicalName)
TYPE node.
If type is specified via its canonical name - canonical name will be returned,
else - short type's name.type - TYPE node.isCanonicalName - is given name canonical.private static boolean isPrimitive(DetailAST type)
IDENT token - it's a
primitive type.type - Ast TYPE node.private static java.lang.String getCanonicalName(DetailAST type)
TYPE node.type - DetailAST TYPE node.private static DetailAST getNextSubTreeNode(DetailAST currentNodeAst, DetailAST subTreeRootAst)
currentNodeAst - Current node in consideringsubTreeRootAst - SubTree rootprivate static java.util.List<java.lang.String> getClassShortNames(java.util.List<java.lang.String> canonicalClassNames)
canonicalClassNames - canonical class names.private static java.lang.String getClassShortName(java.lang.String canonicalClassName)
canonicalClassName - canonical class name.private DetailAST findMatchingAnnotation(DetailAST variableDef)
This method will not look for imports or package statements to detect the passed in annotation.
To check if an AST contains a passed in annotation taking into account fully-qualified names (ex: java.lang.Override, Override) this method will need to be called twice. Once for each name given.
variableDef - variable def node.Copyright © 2001-2022. All Rights Reserved.