diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
index 6af5841403d..913e58aed72 100644
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -333,18 +333,20 @@ public String toGenericString() {
                 if (isAnnotation()) {
                     sb.append('@');
                 }
-                if (isValue()) {
-                    sb.append("value ");
-                }
                 if (isInterface()) { // Note: all annotation interfaces are interfaces
                     sb.append("interface");
                 } else {
                     if (isEnum())
                         sb.append("enum");
-                    else if (isRecord())
-                        sb.append("record");
-                    else
-                        sb.append("class");
+                    else {
+                        if (isValue()) {
+                            sb.append("value ");
+                        }
+                        if (isRecord())
+                            sb.append("record");
+                        else
+                            sb.append("class");
+                    }
                 }
                 sb.append(' ');
                 sb.append(getName());
@@ -611,36 +613,34 @@ public static Class<?> forName(Module module, String name) {
     }
 
     /**
-     * {@return {@code true} if this {@code Class} object represents an identity
-     * class or interface; otherwise {@code false}}
+     * {@return {@code true} if this {@code Class} object represents an identity class;
+     * otherwise {@code false}}
      *
-     * If this {@code Class} object represents an array type, then this method
-     * returns {@code true}.
-     * If this {@code Class} object represents a primitive type, or {@code void},
-     * then this method returns {@code false}.
+     * If this {@code Class} object represents an array type then this method returns {@code true}.
+     * If this {@code Class} object represents an interface, a primitive type, or {@code void}
+     * this method returns {@code false}.
      *
+     * @see AccessFlag#IDENTITY
      * @since Valhalla
      */
     @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
     public native boolean isIdentity();
 
     /**
-     * {@return {@code true} if this {@code Class} object represents a value
-     * class; otherwise {@code false}}
+     * {@return {@code true} if this {@code Class} object represents a value class;
+     * otherwise {@code false}}
+     * All classes that are not {@linkplain #isIdentity identity classes} are value classes.
      *
-     * If this {@code Class} object represents an array type, an interface,
-     * a primitive type, or {@code void}, then this method returns {@code false}.
+     * If this {@code Class} object represents an array type then this method returns {@code false}.
+     * If this {@code Class} object represents an interface, a primitive type, or {@code void}
+     * this method returns {@code true}.
      *
+     * @see AccessFlag#IDENTITY
      * @since Valhalla
      */
     @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
     public boolean isValue() {
-        if (!PreviewFeatures.isEnabled()) {
-            return false;
-        }
-         if (isPrimitive() || isArray() || isInterface())
-             return false;
-        return ((getModifiers() & Modifier.IDENTITY) == 0);
+        return PreviewFeatures.isEnabled() ? !isIdentity() : false;
     }
 
     /**
diff --git a/src/java.base/share/classes/java/lang/IdentityException.java b/src/java.base/share/classes/java/lang/IdentityException.java
index c6a5ca0563d..e4b0fb026c1 100644
--- a/src/java.base/share/classes/java/lang/IdentityException.java
+++ b/src/java.base/share/classes/java/lang/IdentityException.java
@@ -30,7 +30,8 @@
  * <p>
  * Identity objects are required for synchronization and locking.
  * <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">Value-based</a>
- * objects do not have identity and cannot be used for synchronization or locking.
+ * objects do not have identity and cannot be used for synchronization, locking,
+ * or any type of {@link java.lang.ref.Reference}.
  *
  * @since Valhalla
  */
diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java
index e02893cd948..6fbaae32388 100644
--- a/src/java.base/share/classes/java/lang/Object.java
+++ b/src/java.base/share/classes/java/lang/Object.java
@@ -31,10 +31,17 @@
  * Class {@code Object} is the root of the class hierarchy.
  * Every class has {@code Object} as a superclass. All objects,
  * including arrays, implement the methods of this class.
- * <p>
- * Subclasses of {@code java.lang.Object} can be either an {@linkplain Class#isIdentity identity class}
- * or a {@linkplain Class#isValue value class}.
- * See {@jls The Java Language Specification 8.1.1.5 Value Classes}.
+ *
+ * <div class="preview-block">
+ *      <div class="preview-comment">
+ *          When preview features are enabled, subclasses of {@code java.lang.Object} can be either
+ *          an {@linkplain Class#isIdentity identity class} or a {@linkplain Class#isValue value class}.
+ *          See {@jls The Java Language Specification 8.1.1.5 Value Classes}.
+ *          Use of value class instances for synchronization, mutexes, or with
+ *          {@linkplain java.lang.ref.Reference object references} result in
+ *          {@link IdentityException}.
+ *      </div>
+ * </div>
  *
  * @see     java.lang.Class
  * @since   1.0
diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java
index b2de7d6993f..d7afa5344f2 100644
--- a/src/java.base/share/classes/java/lang/System.java
+++ b/src/java.base/share/classes/java/lang/System.java
@@ -471,6 +471,21 @@ public static native void arraycopy(Object src,  int  srcPos,
      * hashCode().
      * The hash code for the null reference is zero.
      *
+     * <div class="preview-block">
+     *      <div class="preview-comment">
+     *          The "identity hash code" of a {@linkplain Class#isValue() value object}
+     *          is computed by combining the identity hash codes of the value object's fields recursively.
+     *      </div>
+     * </div>
+     * @apiNote
+     * <div class="preview-block">
+     *      <div class="preview-comment">
+     *          Note that, like ==, this hash code exposes information about a value object's
+     *          private fields that might otherwise be hidden by an identity object.
+     *          Developers should be cautious about storing sensitive secrets in value object fields.
+     *      </div>
+     * </div>
+     *
      * @param x object for which the hashCode is to be calculated
      * @return  the hashCode
      * @since   1.1
diff --git a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
index a7d6217988e..282aa257aaf 100644
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -596,7 +596,7 @@ LoadableDescriptorsAttributeBuilder add(MethodType... mtypes) {
         }
 
         boolean requiresLoadableDescriptors(Class<?> cls) {
-            return cls.isValue() && cls.accessFlags().contains(AccessFlag.FINAL);
+            return cls.isValue() && cls.accessFlags().contains(AccessFlag.FINAL) && !cls.isPrimitive();
         }
 
         boolean isEmpty() {
diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java
index 48a6d7b28df..5a11bada32a 100644
--- a/src/java.base/share/classes/java/util/IdentityHashMap.java
+++ b/src/java.base/share/classes/java/util/IdentityHashMap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,8 @@
 
 /**
  * This class implements the {@code Map} interface with a hash table, using
- * reference-equality in place of object-equality when comparing keys (and
- * values).  In other words, in an {@code IdentityHashMap}, two keys
+ * `==` in place of object-equality when comparing keys (and values).
+ * In other words, in an {@code IdentityHashMap}, two keys
  * {@code k1} and {@code k2} are considered equal if and only if
  * {@code (k1==k2)}.  (In normal {@code Map} implementations (like
  * {@code HashMap}) two keys {@code k1} and {@code k2} are considered equal
diff --git a/src/java.base/share/classes/java/util/Objects.java b/src/java.base/share/classes/java/util/Objects.java
index 7085323ce1e..f732401819a 100644
--- a/src/java.base/share/classes/java/util/Objects.java
+++ b/src/java.base/share/classes/java/util/Objects.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 import jdk.internal.javac.PreviewFeature;
 import jdk.internal.util.Preconditions;
 import jdk.internal.vm.annotation.ForceInline;
-import jdk.internal.misc.Unsafe;
 
 import java.util.function.Supplier;
 
@@ -180,19 +179,38 @@ public static String toIdentityString(Object o) {
     }
 
    /**
-    * {@return {@code true} if the specified object reference is an identity object,
-    * otherwise {@code false}}
+    * {@return {@code true} if the object is a non-null reference
+    * to an {@linkplain Class#isIdentity() identity object}, otherwise {@code false}}
     *
-    * @param obj an object
-    * @throws NullPointerException if {@code obj} is {@code null}
+    * @apiNote
+    * If the parameter is {@code null}, there is no object
+    * and hence no class to check for identity; the return is {@code false}.
+    * To test for a {@linkplain Class#isValue() value object} use:
+    * {@snippet type="java" :
+    *     if (obj != null && !Objects.hasIdentity(obj)) {
+    *         // obj is a non-null value object
+    *     }
+    * }
+    * @param obj an object or {@code null}
     * @since Valhalla
     */
    @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS)
 //    @IntrinsicCandidate
     public static boolean hasIdentity(Object obj) {
-        requireNonNull(obj);
-        return obj.getClass().isIdentity() ||  // Before Valhalla all classes are identity classes
-                obj.getClass() == Object.class;
+        return (obj == null) ? false : obj.getClass().isIdentity();
+    }
+
+   /**
+    * {@return {@code true} if the object is a non-null reference
+    * to an {@linkplain Class#isValue() value object}, otherwise {@code false}}
+    *
+    * @param obj an object or {@code null}
+    * @since Valhalla
+    */
+   @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS)
+//    @IntrinsicCandidate
+    public static boolean isValueObject(Object obj) {
+        return (obj == null) ? false : obj.getClass().isValue();
     }
 
     /**
diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java
index 276e8731d84..8418a7c7d42 100644
--- a/src/java.base/share/classes/java/util/WeakHashMap.java
+++ b/src/java.base/share/classes/java/util/WeakHashMap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,8 @@
 
 package java.util;
 
-import java.lang.ref.WeakReference;
 import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
@@ -122,6 +122,22 @@
  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
  * Java Collections Framework</a>.
  *
+ * @apiNote
+ * <div class="preview-block">
+ *      <div class="preview-comment">
+ *          Objects that are {@linkplain Class#isValue() value objects} do not have identity
+ *          and can not be used as keys in a {@code WeakHashMap}. {@linkplain java.lang.ref.Reference References}
+ *          such as {@linkplain WeakReference WeakReference} used by {@code WeakhashMap}
+ *          to hold the key cannot refer to a value object.
+ *          Methods such as {@linkplain #get get} or {@linkplain #containsKey containsKey}
+ *          will always return {@code null} or {@code false} respectively.
+ *          The methods such as {@linkplain #put put}, {@linkplain #putAll putAll},
+ *          {@linkplain #compute(Object, BiFunction) compute}, and
+ *          {@linkplain #computeIfAbsent(Object, Function) computeIfAbsent} or any method putting
+ *          a value object, as a key, throw {@link IdentityException}.
+ *      </div>
+ * </div>
+ *
  * @param <K> the type of keys maintained by this map
  * @param <V> the type of mapped values
  *
@@ -288,6 +304,8 @@ static Object unmaskNull(Object key) {
     /**
      * Checks for equality of non-null reference x and possibly-null y.  By
      * default uses Object.equals.
+     * The key may be a value object, but it will never be equal to the referent
+     * so does not need a separate Objects.hasIdentity check.
      */
     private boolean matchesKey(Entry<K,V> e, Object key) {
         // check if the given entry refers to the given key without
@@ -456,9 +474,11 @@ Entry<K,V> getEntry(Object key) {
      *         {@code null} if there was no mapping for {@code key}.
      *         (A {@code null} return can also indicate that the map
      *         previously associated {@code null} with {@code key}.)
+     * @throws IdentityException if {@code key} is a value object
      */
     public V put(K key, V value) {
         Object k = maskNull(key);
+        Objects.requireIdentity(k);
         int h = hash(k);
         Entry<K,V>[] tab = getTable();
         int i = indexFor(h, tab.length);
@@ -548,6 +568,7 @@ private void transfer(Entry<K,V>[] src, Entry<K,V>[] dest) {
      *
      * @param m mappings to be stored in this map.
      * @throws  NullPointerException if the specified map is null.
+     * @throws  IdentityException if any of the {@code keys} is a value object
      */
     public void putAll(Map<? extends K, ? extends V> m) {
         int numKeysToBeAdded = m.size();
diff --git a/test/jdk/java/lang/Class/GenericStringTest.java b/test/jdk/java/lang/Class/GenericStringTest.java
index 73a3ffed5ad..d0f2cd2c13d 100644
--- a/test/jdk/java/lang/Class/GenericStringTest.java
+++ b/test/jdk/java/lang/Class/GenericStringTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/test/jdk/java/util/Collection/MOAT.java b/test/jdk/java/util/Collection/MOAT.java
index 1a4e5503f63..d98559fa819 100644
--- a/test/jdk/java/util/Collection/MOAT.java
+++ b/test/jdk/java/util/Collection/MOAT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
  * @bug     6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
  *          4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
  *          6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
- *          4802647 7123424 8024709 8193128 8327858
+ *          4802647 7123424 8024709 8193128 8327858 8346307
  * @summary Run many tests on many Collection and Map implementations
  * @author  Martin Buchholz
  * @modules java.base/java.util:open
diff --git a/test/jdk/java/util/WeakHashMapValues.java b/test/jdk/java/util/WeakHashMapValues.java
new file mode 100644
index 00000000000..774f3ade96b
--- /dev/null
+++ b/test/jdk/java/util/WeakHashMapValues.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.HashMap;
+import java.util.WeakHashMap;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/*
+ * @test
+ * @summary Check WeakHashMap throws IdentityException when Value Objects are put
+ * @enablePreview
+ * @run junit WeakHashMapValues
+ */
+public class WeakHashMapValues {
+
+    /*
+     * Check that any kind of put with a value class as a key throws IdentityException
+     */
+    @Test
+    void checkThrowsIdentityException() {
+        WeakHashMap<Object, Object> whm = new WeakHashMap<>();
+        Object key = new Foo(1);
+        assertThrows(IdentityException.class, () -> whm.put(key, "1"));
+        assertThrows(IdentityException.class, () -> whm.putIfAbsent(key, "2"));
+        assertThrows(IdentityException.class, () -> whm.compute(key, (_, _) -> "3"));
+        assertThrows(IdentityException.class, () -> whm.computeIfAbsent(key, (_) -> "4"));
+
+        HashMap<Object, String> hmap = new HashMap<>();
+        hmap.put(key, "6");
+        assertThrows(IdentityException.class, () -> whm.putAll(hmap));
+    }
+
+    /*
+     * Check that any kind of put with Integer as a value class as a key throws IdentityException
+     */
+    @Test
+    void checkIntegerThrowsIdentityException() {
+        WeakHashMap<Object, Object> whm = new WeakHashMap<>();
+        Object key = 1;
+        assertThrows(IdentityException.class, () -> whm.put(key, "1"));
+        assertThrows(IdentityException.class, () -> whm.putIfAbsent(key, "2"));
+        assertThrows(IdentityException.class, () -> whm.compute(key, (_, _) -> "3"));
+        assertThrows(IdentityException.class, () -> whm.computeIfAbsent(key, (_) -> "4"));
+
+        HashMap<Object, String> hmap = new HashMap<>();
+        hmap.put(key, "6");
+        assertThrows(IdentityException.class, () -> whm.putAll(hmap));
+
+    }
+
+    /**
+     * Check that queries with a value object return false or null.
+     */
+    @Test
+    void checkValueObjectGet() {
+        WeakHashMap<Object, Object> whm = new WeakHashMap<>();
+        Object key = "X";
+        Object v = new Foo(1);
+        assertEquals(whm.get(v), null, "Get of value object should return null");
+        assertEquals(whm.containsKey(v), false, "containsKey should return false");
+    }
+}
+
+value class Foo {
+    int x;
+    Foo(int x) {
+        this.x = x;
+    }
+}
diff --git a/test/jdk/valhalla/valuetypes/ObjectMethods.java b/test/jdk/valhalla/valuetypes/ObjectMethods.java
index 90cc9c5a949..45a746bbf1e 100644
--- a/test/jdk/valhalla/valuetypes/ObjectMethods.java
+++ b/test/jdk/valhalla/valuetypes/ObjectMethods.java
@@ -29,9 +29,13 @@
  * @run junit/othervm -Dvalue.bsm.salt=1 -XX:-UseAtomicValueFlattening ObjectMethods
  * @run junit/othervm -Dvalue.bsm.salt=1 -XX:-UseFieldFlattening ObjectMethods
  */
+import java.util.Optional;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.Function;
 import java.util.stream.Stream;
+import java.lang.reflect.AccessFlag;
+import java.lang.reflect.Modifier;
 
 import jdk.internal.value.ValueClass;
 import jdk.internal.vm.annotation.NullRestricted;
@@ -108,12 +112,13 @@ static value record ValueRecord(int i, String name) {}
     static final Ref R2 = new Ref(P2, null);
     static final Value V = new Value(P1, L1, R1, "value");
 
+    // Instances to test, classes of each instance are tested too
     static Stream<Arguments> identitiesData() {
+        Function<String, String> lambda1 = (a) -> "xyz";
         return Stream.of(
-                Arguments.of(new Object(), true, false),
+                Arguments.of(lambda1, true, false),         // a lambda (Identity for now)
+                Arguments.of(new Object(), true, false),    // java.lang.Object
                 Arguments.of("String", true, false),
-                Arguments.of(String.class, true, false),
-                Arguments.of(Object.class, true, false),
                 Arguments.of(L1, false, true),
                 Arguments.of(V, false, true),
                 Arguments.of(new ValueRecord(1, "B"), false, true),
@@ -124,27 +129,54 @@ static Stream<Arguments> identitiesData() {
         );
     }
 
+    // Classes to test
+    static Stream<Arguments> classesData() {
+        return Stream.of(
+                Arguments.of(int.class, false, true),       // Fabricated primitive classes
+                Arguments.of(long.class, false, true),
+                Arguments.of(short.class, false, true),
+                Arguments.of(byte.class, false, true),
+                Arguments.of(float.class, false, true),
+                Arguments.of(double.class, false, true),
+                Arguments.of(char.class, false, true),
+                Arguments.of(void.class, false, true),
+                Arguments.of(String.class, true, false),
+                Arguments.of(Object.class, true, false),
+                Arguments.of(Function.class, false, true),  // Interface
+                Arguments.of(Optional.class, false, true),  // Concrete value classes...
+                Arguments.of(Character.class, false, true)
+        );
+    }
+
     @ParameterizedTest
     @MethodSource("identitiesData")
     public void identityTests(Object obj, boolean identityClass, boolean valueClass) {
         Class<?> clazz = obj.getClass();
+        assertEquals(identityClass, Objects.hasIdentity(obj), "Objects.hasIdentity(" + obj + ")");
 
-        if (clazz == Object.class) {
-            assertTrue(Objects.hasIdentity(obj), "Objects.hasIdentity()");
-        } else {
-            assertEquals(identityClass, Objects.hasIdentity(obj), "Objects.hasIdentity()");
-        }
+        // Run tests on the class
+        classTests(clazz, identityClass, valueClass);
+    }
+
+    @ParameterizedTest
+    @MethodSource("classesData")
+    public void classTests(Class<?> clazz, boolean identityClass, boolean valueClass) {
+        assertEquals(identityClass, clazz.isIdentity(), "Class.isIdentity(): " + clazz);
 
-        assertEquals(identityClass, clazz.isIdentity(), "Class.isIdentity()");
+        assertEquals(valueClass, clazz.isValue(), "Class.isValue(): " + clazz);
 
-        assertEquals(valueClass, clazz.isValue(), "Class.isValue()");
+        assertEquals(clazz.accessFlags().contains(AccessFlag.IDENTITY),
+                identityClass, "AccessFlag.IDENTITY: " + clazz);
 
-        // JDK-8294866: Not yet implemented checks of AccessFlags for the array class
-//        assertEquals(clazz.accessFlags().contains(AccessFlag.IDENTITY),
-//                identityClass, "AccessFlag.IDENTITY");
-//
-//        assertEquals(clazz.accessFlags().contains(AccessFlag.VALUE),
-//                valueClass, "AccessFlag.VALUE");
+        int modifiers = clazz.getModifiers();
+        assertEquals(clazz.isIdentity(), (modifiers & Modifier.IDENTITY) != 0, "Class.getModifiers() & IDENTITY != 0");
+        assertEquals(clazz.isValue(), (modifiers & Modifier.IDENTITY) == 0, "Class.getModifiers() & IDENTITY == 0");
+    }
+
+    @Test
+    public void identityTestNull() {
+        assertFalse(Objects.hasIdentity(null), "Objects.hasIdentity(null)");
+        assertFalse(Objects.isValueObject(null), "Objects.isValueObject(null)");
     }
 
     static Stream<Arguments> equalsTests() {