Why is it possible to use an ImmutableList with parcel.readList?
void someParcelFunction(Parcel parcel) {
ImmutableList<String> myList = ImmutableList.of();
parcel.readList(myList, ImmutableList.class.getClassLoader(), String.class);
}
When I look at the source code for parcel.readList I can see that the add method is called on the outVal (first argument) of the method:
private <T> void readListInternal(@NonNull List<? super T> outVal, int n,
@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
while (n > 0) {
T value = readValue(loader, clazz);
//Log.d(TAG, "Unmarshalling value=" + value);
outVal.add(value);
n--;
}
}
But in Guava's documentation it looks like this method is deprecated and should throw an UnsupportedOperationException: https://guava.dev/releases/20.0/api/docs/com/google/common/collect/ImmutableList.html#add-int-E-. And this would make sense because not only should an Immutable list be immutable, but I am also initialising this list to empty and then it seems like it's actually being modified.
However, the code above runs and no exceptions are thrown. Why is that?
It doesn't. Possibly you are either not running the code you think you are running, or you're attempting to read in a 0-len list, which ends up never calling
add, thus never causing any problem.The fact that the method is deprecated is irrelevant - that is a compile-time (i.e. 'as you write it', not 'as you run it') only feature that means that invoking
.addon an expression whose type isImmutableListgets you a warning, but invoking it on an expression whose type isList(and an ImmutableList is a kind of list, so, that's possible, and in fact exactly what happens inreadList's implementation) causes no issues, and@deprecateddoesn't do anything else.The fact that ImmutableList's
addimplementation straight up throws - that would, of course, do something at runtime. In fact, readList cannot possibly get around this. Hence, either you aren't running what you think you are running, or, you're reading a 0-len list, in which case that while loop is skipped immediately, andoutVal.addis never invoked.