## Why is this an issue?

Public fields in public classes do not respect the encapsulation principle and have three main disadvantages:

- Additional behavior such as validation cannot be added.
- The internal representation is exposed, and cannot be changed afterwards.
- Member values are subject to change from anywhere in the code and may not meet the programmer’s assumptions.

To prevent unauthorized modifications, private attributes and accessor methods (set and get) should be used.

### What is the potential impact?

Public fields can be modified by any part of the code and this can lead to unexpected changes and hard-to-trace bugs.

Public fields don’t hide the implementation details. As a consequence, it is no longer possible to change how the data is stored internally without impacting the client code of the class.

The code is harder to maintain.

### Exceptions

This rule ignores `public final` fields because they are not modifiable. Also, annotated fields, whatever the annotation(s) will be ignored, as annotations are often used by injection frameworks, which in exchange require having public fields.

## How to fix it

Depending on your need there are multiple options:

- Encapsulate the field
  1. Make the field private.
  2. Define methods to get and set the value of the field.
     These methods are commonly known as getter and setter methods and are prefixed by `get` and `set` followed by the name of the field. Note: as a bonus it is now possible to monitor value changes using breakpoints.
- Mark the field as `public final` if it is not supposed to change.

### Code examples

#### Noncompliant code example

    public class MyClass {

      public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked

      public String firstName;                       // Noncompliant

    }

#### Compliant solution

    public class MyClass {

      public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked

      private String firstName;

      public String getFirstName() {
        return firstName;
      }

      public void setFirstName(String firstName) {
        this.firstName = firstName;
      }

    }

### How does this work?

By having a setter and a getter the code can control how the field is accessed and modified. For example, adding validation in the setter method will ensure that only valid values are set.

The access modifiers on the setter can also be changed to `private` or `protected` to restrain which code can modify the value.

## Resources

- CWE - CWE-493 - Critical Public Variable Without Final Modifier