3

I would like to extends Collections.UnmodifiableRandomAccessList with a custom hashCode/equals implementation, but without the mess of delegation or copying and pasting the implementation. In trusted code, I thought it would be easy. However, my attempt to declare my new class in package java.util gave me a SecurityException. Is there any way around it?

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
  • 6
    You can't extend a package-private class in a different package -- that's the whole point of the access modifier. You could try uninstalling the SecurityManager, I suppose, to see if that allows you to declare your own `java.util` package. But why is the default hashCode()/equals() insufficient? – Thorn G Jan 26 '15 at 11:50
  • @TomG I'm extending it in the **same** package. There is no SecurityManager. Performance. – Aleksandr Dubinsky Jan 26 '15 at 11:57
  • possible duplicate of [How to make the jvm load my java.lang.String instead of the one in rt.jar](http://stackoverflow.com/questions/22060752/how-to-make-the-jvm-load-my-java-lang-string-instead-of-the-one-in-rt-jar) – Joe Jan 26 '15 at 12:01
  • It's very hard to extend classes in the java.* packages - the runtime actively prevents you doing so, and it's a violation of the spec. You would have to do the hacking in @Joe's duplicate link. – artbristol Jan 26 '15 at 12:06
  • @Joe Thanks, but that question is different. It wants to replace an existing class, I want to add a new class that extends an existing class. – Aleksandr Dubinsky Jan 26 '15 at 12:09

2 Answers2

2

If you were able to override it, it would give you the opportunity to allow editing the state, which contradicts the purpose of the class (immutability). Java chose to include this as package-private, but in other instances (like String) these precautions are implemented using final instead, also to prevent subclassing.

[addendum] Both hashCode/equals delegate to the list being wrapped, so subclassing the list being wrapped will also change the behavior of the UnmodifiableRandomAccessList.

Mark Jeronimus
  • 9,278
  • 3
  • 37
  • 50
  • 1
    -1 I'm not asking for the reasons. Moreover, in trusted code (without a SecurityManager), I'm free to do things that violate encapsulation and security. (Like using reflection on private fields or even accessing raw memory.) – Aleksandr Dubinsky Jan 26 '15 at 11:54
  • Why not wrap all calls to Collections.unmodifiableList(new MyCustomList<>(realList))? instead and implement hashcode and equals in MyCustomList ? – jontro Jan 26 '15 at 16:34
2

HotSpot uses at least three ClassLoaders that are responsible for loading classes into the JVM. The system ClassLoader (the one that loads user code) refuses to load classes into certain namespaces like java and java.util (but not, eg, java.nio). AFAIK, there is no way to convince it otherwise. The solution is to ask the bootstrap ClassLoader (the one that loads Java's base classes) to do it, via the -Xbootclasspath/a JVM switch as documented here.

Btw, for conveniently implementing a List that delegates to another implementation, see Guava's ForwardingList.

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99