Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

guava's ImmutableList is not really immutable

Tags:

java

guava

ImmutableList's documentation says:

Although this class is not final, it cannot be subclassed as it has no public or protected constructors.

I know it's a little bit far-fetched, but it's possible to create a subclass of ImmutableList in com.google.common.collect package (since its constructor is not private, but package private) which is mutable. From that point, no one who gets a reference to an ImmutableList can be sure that it really is immutable. Does this not break the purpose of ImmutableList?

like image 880
Katona Avatar asked Jul 30 '13 09:07

Katona


2 Answers

At the end of the day, Guava is just a bunch of binary you're executing. You can do anything you want with it, including violate the contracts that code provides.

You can:

  • Run a custom JVM that breaks Guava
  • Run a separate application and manipulate the JVM's physical memory and break Guava
  • Manipulate the Guava bytecode and break Guava
  • Configure the classloaders to load other bytecode and break Guava
  • Make calls to sun.misc.Unsafe to break Guava
  • Use reflection to break Guava
  • Abuse the package hierarchy and break Guava

Just to name a few. None of these are novel, unique to Guava, or unique to Java. It's your machine, you should be able to do these things. Of course what you can do and what you should do are very different things. Abusing Java in any of these ways will lead to problems for you and anyone else who tries to run your code.

The Java type system, including visibility restrictions, is not a police officer. It exists to help you write quality code that's easy to work with. Guava takes advantage of the documented behavior of Java to give you even more tools that enable you to write more quality code that's even easier to work with. If you choose to break the tools that's your prerogative. But don't expect anyone to want to work with your code.


To specifically address this point:

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

You can, without very much work, manipulate a private-constructor class into being mutable in much the same way. Abusing the package hierarchy, as I mentioned above, is just one of many things you simply should not do. If you don't trust a piece of third-party code to be well-behaved in this regard, you should not use it.

like image 160
dimo414 Avatar answered Oct 23 '22 03:10

dimo414


Even if you extend ImmutableList you will not be able to make it mutable because all its mutator methods are final, like this one:

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

and its iterator returns UnmodifiableIterator whose remove method is final too

like image 44
Evgeniy Dorofeev Avatar answered Oct 23 '22 02:10

Evgeniy Dorofeev