javaandroidlistparcelimmutablelist

Why does Android's parcel.readList work with ImmutableList?


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?


Solution

  • 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 .add on an expression whose type is ImmutableList gets you a warning, but invoking it on an expression whose type is List (and an ImmutableList is a kind of list, so, that's possible, and in fact exactly what happens in readList's implementation) causes no issues, and @deprecated doesn't do anything else.

    The fact that ImmutableList's add implementation 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, and outVal.add is never invoked.