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.