VisibilityModifier

Since Checkstyle 3.0

Description

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 want to 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:

  • It's declared as final
  • Has either a primitive type or instance of class user defined to be immutable (such as String, ImmutableCollection from Guava, etc.)

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.

Properties

name description type default value since
allowPublicFinalFields Allow final fields to be declared as public. boolean false 7.0
allowPublicImmutableFields Allow immutable fields to be declared as public if defined in final class. boolean false 6.4
ignoreAnnotationCanonicalNames Specify annotations canonical names which ignore variables in consideration. String[] com.google.common.annotations.VisibleForTesting, org.junit.ClassRule, org.junit.Rule 6.5
immutableClassCanonicalNames Specify immutable classes canonical names. String[] 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 6.4.1
packageAllowed Control whether package visible members are allowed. boolean false 3.0
protectedAllowed Control whether protected members are allowed. boolean false 3.0
publicMemberPattern Specify pattern for public members that should be ignored. Pattern "^serialVersionUID$" 3.0

Examples

To configure the check:

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

Example with default values:

class Example1 {
  private int myPrivateField1;

  int field1; // violation, must have a visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  public int field3 = 42; // violation, not final 'must be private'

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final int field5 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final java.lang.String notes = null;

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the check so that it allows package visible members:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="packageAllowed" value="true"/>
    </module>
  </module>
</module>
        

Example of allowed package visible members:

class Example2 {
  private int myPrivateField1;

  int field1;

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final int field5 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final java.lang.String notes = null;

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString;

  @Deprecated
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the check so that it allows protected visible members:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="protectedAllowed" value="true"/>
    </module>
  </module>
</module>
        

Example of allowed protected visible members:

class Example3 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2;

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final int field5 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final java.lang.String notes = null;

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the check so that it allows no public members:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="publicMemberPattern" value="^$"/>
    </module>
  </module>
</module>
        

Example of not allowed public members:

class Example4 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  // violation below, doesn't match the pattern 'must be private'
  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final int field5 = 42;

  // violation below, public immutable fields are not allowed 'must be private'
  public final java.lang.String notes = null;

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the Check so that it allows public immutable fields (mostly for immutable classes):

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="allowPublicImmutableFields" value="true"/>
    </module>
  </module>
</module>
        

Example of allowed public immutable fields:

class Example5 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  public final int field5 = 42; // violation 'must be private'

  public final java.lang.String notes = null; // violation 'must be private'

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the Check in order to allow user specified immutable class names:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="allowPublicImmutableFields" value="true"/>
      <property name="immutableClassCanonicalNames"
                value="com.google.common.collect.ImmutableSet,
                       java.lang.String"/>
    </module>
  </module>
</module>
        

Example of allowed public immutable fields:

class Example6 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  public final int field5 = 42; // violation 'must be private'

  public final java.lang.String notes = null; // violation 'must be private'

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

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="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="allowPublicImmutableFields" value="true"/>
      <property name="immutableClassCanonicalNames"
                value="com.google.common.collect.ImmutableSet,
                       java.lang.String, com.google.common.collect.ImmutableMap"/>
    </module>
  </module>
</module>
        

Example of how the check works:

class Example7 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  public final int field5 = 42; // violation 'must be private'

  public final java.lang.String notes = null; // violation 'must be private'

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the Check passing fields annotated with @java.lang.Deprecated:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="ignoreAnnotationCanonicalNames"
                value="java.lang.Deprecated"/>
    </module>
  </module>
</module>
        

Example of allowed field:

class Example8 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  public final int field5 = 42; // violation 'must be private'

  public final java.lang.String notes = null; // violation 'must be private'

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString;

  @Deprecated
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  // violation below, annotation not configured 'must be private'
  public String testString = "";
}
        

To configure the Check passing fields annotated with @org.junit.Rule, @org.junit.ClassRule and @com.google.common.annotations.VisibleForTesting annotations:

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

Example of allowed fields:

class Example9 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  public final int field5 = 42; // violation 'must be private'

  public final java.lang.String notes = null; // violation 'must be private'

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  // violation below, annotation not configured 'must be private'
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  public String testString = "";
}
        

To configure the Check passing fields annotated with short annotation name:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="ignoreAnnotationCanonicalNames" value="Deprecated"/>
    </module>
  </module>
</module>
        

Example of allowed fields:

class Example10 {
  private int myPrivateField1;

  int field1; // violation, must have visibility modifier 'must be private'

  protected String field2; // violation, protected not allowed 'must be private'

  // violation below, not final nor matching pattern 'must be private'
  public int field3 = 42;

  public long serialVersionUID = 1L;

  public static final int field4 = 42;

  public final int field5 = 42; // violation 'must be private'

  public final java.lang.String notes = null; // violation 'must be private'

  // violation below, HashSet is mutable 'must be private'
  public final Set<String> mySet1 = new HashSet<>();

  // violation below, immutable type not in config 'must be private'
  public final ImmutableSet<String> mySet2 = null;

  // violation below, immutable type not in config 'must be private'
  public final ImmutableMap<String, Object> objects1 = null;

  @java.lang.Deprecated
  String annotatedString; // violation, annotation not configured 'must be private'

  @Deprecated
  String shortCustomAnnotated;

  @com.google.common.annotations.VisibleForTesting
  // violation below, annotation not configured 'must be private'
  public String testString = "";
}
        

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="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="allowPublicImmutableFields" value="true"/>
    </module>
  </module>
</module>
        

Code example:

class Example11 {
  public final int someIntValue = 0; // violation 'must be private'

  public final ImmutableSet<String> includes = null; // violation 'must be private'

  public final java.lang.String notes = ""; // violation 'must be private'

  public final BigDecimal value = null; // violation 'must be private'

  public final List list = null; // violation 'must be private'
}
        

2) To configure the check to use only 'allowPublicFinalFields' option:

<module name="Checker">
  <module name="TreeWalker">
    <module name="VisibilityModifier">
      <property name="allowPublicFinalFields" value="true"/>
    </module>
  </module>
</module>
        

Code example:

class Example12 {
  public final int someIntValue = 0;

  public final ImmutableSet<String> includes = null;

  public final java.lang.String notes = "";

  public final BigDecimal value = null;

  public final List list = null;
}
        

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

Parent Module

TreeWalker