Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of sun.misc.SharedSecrets

Tags:

java

I found this little gem in our codebase at work recently. I have to confess that I have absolutely no idea why this enum was written in this way (names changed to protect the innocent):

package foo.bar;

import sun.misc.SharedSecrets;
import foo.baz.HasAGetValuesMethod;

public enum MysteryEnum implements HasAGetValuesMethod {

   THINGY, BOB;

   @Override
   public MysteryEnum[] getValues() {
      return SharedSecrets.getJavaLangAccess().getEnumConstantsShared(MysteryEnum .class);
   }
}

In the getValues() method instead of simply calling MysteryEnum.values() it's using something called sun.misc.SharedSecret to get a handle to something called sun.misc.JavaLangAccess, then using that to get an array of all the enum values. The Javadoc on that class tells you what the method does, but I can't find much on why you would want to call it.

The developer that wrote this is no longer around, so I can't ask him. I'm going to ask my team anyway, but I have a feeling that the answer will be: "Don't know why it does that, but better not change it". For the moment, I'm assuming that this is either an odd case of someone not knowing that the values() method exists, or that my ignorance of the sun.misc libraries is causing me to miss something obvious to others. Any idea's why this code was written this way?

like image 713
Jon Avatar asked Jan 31 '12 11:01

Jon


1 Answers

The method returns the same array without reflection or copying/cloning the underlying array. This improves performance, but is not a good idea to exposes a mutable array.

for (int i = 0; i < 3; i++)
    System.out.println(SharedSecrets.getJavaLangAccess().getEnumConstantsShared(AccessMode.class));
AccessMode[] ams = SharedSecrets.getJavaLangAccess().getEnumConstantsShared(AccessMode.class);
ams[1] = ams[2]; // don't do this !!
System.out.println(EnumSet.allOf(AccessMode.class));

prints

[Ljava.nio.file.AccessMode;@330cdec1
[Ljava.nio.file.AccessMode;@330cdec1
[Ljava.nio.file.AccessMode;@330cdec1
[READ, EXECUTE, EXECUTE]

Instead of using this method, what I do is use my own cached copy

// cannot be modified.
private static final AccessMode[] ACCESS_MODES = AccessMode.values();
like image 77
Peter Lawrey Avatar answered Nov 03 '22 16:11

Peter Lawrey