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);

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 .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.

Answered By – rzwitserloot

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published