< prev index next >

src/java.base/share/classes/java/util/HashMap.java

Print this page

        

@@ -23,10 +23,13 @@
  * questions.
  */
 
 package java.util;
 
+import sun.misc.JavaLangAccess;
+import sun.misc.SharedSecrets;
+
 import java.io.IOException;
 import java.io.InvalidObjectException;
 import java.io.Serializable;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;

@@ -337,27 +340,48 @@
         int h;
         return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
     }
 
     /**
-     * Returns x's Class if it is of the form "class C implements
-     * Comparable<C>", else null.
+     * Function returning TRUE for given Class when it is safe to compare
+     * instances of it among themselves.
      */
-    static Class<?> comparableClassFor(Object x) {
-        if (x instanceof Comparable) {
-            Class<?> c; Type[] ts, as; ParameterizedType p;
-            if ((c = x.getClass()) == String.class) // bypass checks
-                return c;
+    private static final Function<Class<?>, Boolean> isSelfComparableClass =
+        new Function<Class<?>, Boolean>() {
+            @Override
+            public Boolean apply(Class<?> c) {
+                Type[] ts, as; ParameterizedType p;
             if ((ts = c.getGenericInterfaces()) != null) {
                 for (Type t : ts) {
                     if ((t instanceof ParameterizedType) &&
                         ((p = (ParameterizedType) t).getRawType() ==
                          Comparable.class) &&
                         (as = p.getActualTypeArguments()) != null &&
                         as.length == 1 && as[0] == c) // type arg is c
+                            return Boolean.TRUE;
+                    }
+                }
+                return Boolean.FALSE;
+            }
+        };
+
+    /**
+     * Returns x's Class if it is of the form "class C implements
+     * Comparable<C>", else null.
+     */
+    static Class<?> comparableClassFor(Object x) {
+        if (x instanceof Comparable) {
+            Class<?> c;
+            if ((c = x.getClass()) == String.class) { // bypass checks
                         return c;
                 }
+            JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+            Boolean scc = (jla != null)
+                ? jla.getGenericDerivative(c, isSelfComparableClass, isSelfComparableClass)
+                : isSelfComparableClass.apply(c); // in case very early in boot-up sequence
+            if (scc != null && scc) {
+                return c;
             }
         }
         return null;
     }
 
< prev index next >