SpotBugs is a great tool for static code analysis. Recently I got two similar warnings in one of the codebases I work on and I had to fix it.
EI_EXPOSE_REP & EI_EXPOSE_REP2 Warning definitions
You can find the official documentation for these two warnings in the SpotBugs documentation.
- Warning EI_EXPOSE_REP
- Warning EI_EXPOSE_REP2
EI_EXPOSE_REP
This warning is mainly about exposing a mutable object from a class. Let’s take a class which has a
mutable object such as a List
.
1public class MyClass {2 private List<String> myList;34 public MyClass() {5 myList = new ArrayList<>();6 }78 public List<String> getMyList() {9 return myList;10 }11}12
Now you can see that we are exposing the myList
object via the getMyList()
method. This means that anyone who has access to the
MyClass
object can modify the myList
object. This is a clear violation of the encapsulation principle in OOP. This is where the
EI_EXPOSE_REP
warning comes in.
The Fix
We can mainly fix this using two approaches.
- Return an unmodifiable list from the
getMyList()
method. You can change the getMyList() method as follows.
1public List<String> getMyList() {2 return Collections.unmodifiableList(myList);3}4
- Return a copy of the list from the
getMyList()
method. You can change the getMyList() method as follows.
1public List<String> getMyList() {2 return List.copyOf(myList);3}4
EI_EXPOSE_REP2
This warning is pretty much related to the previous warning. The only difference is that this warning is about keeping a reference to a mutable object within the class. Let’s take the same example we used in the previous warning.
1public class MyClass {2 private List<String> myList;34 public MyClass(List<String> myList) {5 this.myList = myList;6 }7}8
In the above example you can see how the constructor gets a reference to a mutable List from outside the class and assigns it to the
myList
field. This means that the caller can modify the myList
object from outside of the class. This is again a clear violation of the
encapsulation principle and a security risk.
The Fix
The fix for this warning is slightly different from the previous warning. You can fix this by,
- Creating a copy of the list when assigning it to the
myList
variable.
1public MyClass(List<String> myList) {2 this.myList = List.copyOf(myList);3}4
- Creating an unmodifiable list when assigning it to the
myList
variable.
1public MyClass(List<String> myList) {2 this.myList = Collections.unmodifiableList(myList);3}4
Conclusion
These warnings can be really helpful given the right context. But in some cases, it might be an overkill to fix these warnings. So
it’s always better to analyze the context and decide whether to fix these warnings or not. In case you want to ignore these warnings
you can use the @SuppressFBWarnings
annotation provided by SpotBugs.
1@SuppressFBWarnings("EI_EXPOSE_REP")2public class MyClass {3 private List<String> myList;45 public MyClass() {6 myList = new ArrayList<>();7 }89 public List<String> getMyList() {10 return myList;11 }12}13