Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppress Android Unread Field warning with byte[]

I'm using the java.lang.SuppressWarnings package in Android Studio.

I can't get rid of this one:

EI_EXPOSE_REP2: May expose internal representation by incorporating reference to mutable object (findbugs task)

It is happening with a setter method.

How to get rid of this warning?

 public class PropertyDetailDocumentStorageModel implements Parcelable {
 @SerializedName("picture")
 private byte[] mPicture;    
 public void setmPicture(byte[] mPicture) { this.mPicture = mPicture; }

Warning:

setmPicture(byte[]) may expose internal representation by storing an externally mutable object into PropertyDetailDocumentStorageModel.mPicture

Note this is happening on the only field whose type is byte[]. Other fields in the same class which have getters are not throwing this warning.

like image 923
Greg Avatar asked Dec 30 '15 11:12

Greg


2 Answers

After clarifying some stuff in the comments, I think the answer is this.

  1. URF_UNREAD_FIELD - The field counts as read if a getter exists, because then FindBugs assumes that the field is read from outside the class. If that does not happen, you have some kind of false positive which would require further analysis or suppression.
  2. EI_EXPOSE_REP2 - Arrays are always mutable, so by returning the array from the getter you expose it to modification. You could return a copy of the array via Arrays.copyOf(), or, again, suppress the warning.

FindBugs warnings are suppressed via the @SuppressFBWarnings annotation (doc). You need annotations.jar and jsr305.jar from the FindBugs lib folder on the classpath of the analysis process for FindBugs annotations to work. Example:

@SuppressFBWarnings("URF_UNREAD_FIELD")
like image 135
barfuin Avatar answered Oct 16 '22 18:10

barfuin


So like @Thomas suggested, Arrays are always mutable. The fix was returning a copy of the property instead of the property itself:

public byte[] getmPicture() { return Arrays.copyOf(mPicture, mPicture.length); }

public void setmPicture(final byte[] picture) { this.mPicture = Arrays.copyOf(picture, picture.length); }

instead of

public byte[] getmPicture() { return mPicture; }

public void setmPicture(byte[] picture) { this.mPicture = picture; }

What I didn't know is that for other type like String for example, a simple getter would always return a copy of the object. That is not the case for Arrays.

like image 32
Greg Avatar answered Oct 16 '22 16:10

Greg