Guava ImmutableList is not really immutable

ImmutableList documentation says :

Although this class is not final, it cannot be subclassed because it does not have public or protected constructors.

I know this is a little far-fetched, but you can subclass the ImmutableList in the com.google.common.collect package (since its constructor is not private, but a closed package), which is mutable. From now on, no one who gets a reference to the ImmutableList can be sure that it is really immutable. Doesn't that violate the purpose of the ImmutableList ?

+6
source share
2 answers

At the end of the day, Guava is just a bunch of binary files that you execute. You can do whatever you want with it, including violating the contracts provided by this code.

You can:

  • Run a custom JVM that crashes Guava
  • Launch a standalone application and manipulate the physical memory of the JVM and break Guava
  • Manipulate Guava Bytecode and Break Guava
  • Configure class loaders to load another bytecode and break Guava
  • Make sun.misc.Unsafe calls to break Guava
  • Use reflection to break Guava
  • Break package hierarchy and break guava

Just to name a few. None of them are new, unique to Guava , or unique to Java . This is your car, you should be able to do it all. Of course, what you can do and what you should do are two different things. Overusing Java in any of these ways will cause problems for you and anyone trying to run your code.

A system such as Java, including visibility restrictions, is not a police officer. It exists to help you write quality code that is easy to work with. Guava uses the documented behavior of Java to provide you with even more tools that will allow you to write better code that is even easier to work with. If you decide to break the tools, which is the prerogative. But don't expect someone to want to work with your code.


To specifically address this issue:

it is possible to create a subclass of ImmutableList in the package com.google.common.collect (since its constructor is not private, but a closed package), which is mutable.

You can easily manipulate the private-constructor class as mutable in much the same way. Breaking the package hierarchy, as I mentioned above, is just one of many things you just don't need to do. If you do not trust third-party code to be good in this regard, you should not use it.

+5
source

Even if you extend the ImmutableList , you cannot make it mutable, because all of its mutator methods are final, for example:

  public final void add(int index, E element) { throw new UnsupportedOperationException(); } 

and its iterator returns a UnmodifiableIterator whose delete method is also final

+3
source

Source: https://habr.com/ru/post/950606/


All Articles