1 /*
2 * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8377576
27 * @summary Test jdk.internal.value.ValueClass with and without preview
28 * @modules java.base/jdk.internal.misc
29 * java.base/jdk.internal.value
30 * @run junit ValueClassCompatibilityTest
31 * @run junit/othervm --enable-preview ValueClassCompatibilityTest
32 */
33
34 import java.util.ArrayList;
35 import java.util.Optional;
36
37 import jdk.internal.misc.PreviewFeatures;
38 import jdk.internal.value.ValueClass;
39 import org.junit.jupiter.api.Test;
40
41 import static org.junit.jupiter.api.Assertions.*;
42
43 class ValueClassCompatibilityTest {
44 @Test
45 void testIsValueObjectCompatible() {
46 isValueObjectCompatibleCase(false, int.class, "primitive");
47 isValueObjectCompatibleCase(true, Object.class, "Object");
48 isValueObjectCompatibleCase(true, Number.class, "abstract value class");
49 isValueObjectCompatibleCase(true, Integer.class, "final value class");
50 isValueObjectCompatibleCase(false, ClassValue.class, "abstract identity class");
51 isValueObjectCompatibleCase(false, ArrayList.class, "identity class");
52 isValueObjectCompatibleCase(false, String.class, "final identity class");
53 isValueObjectCompatibleCase(true, Comparable.class, "interface");
54 isValueObjectCompatibleCase(false, int[].class, "array class");
55 isValueObjectCompatibleCase(false, Object[].class, "array class");
56 isValueObjectCompatibleCase(false, Number[].class, "array class");
57 isValueObjectCompatibleCase(false, Integer[].class, "array class");
58 isValueObjectCompatibleCase(false, ClassValue[].class, "array class");
59 isValueObjectCompatibleCase(false, ArrayList[].class, "array class");
60 isValueObjectCompatibleCase(false, String[].class, "array class");
61 isValueObjectCompatibleCase(false, Comparable[].class, "array class");
62 }
63
64 private static void isValueObjectCompatibleCase(boolean expected, Class<?> arg, String classification) {
65 assertEquals(PreviewFeatures.isEnabled() && expected,
66 ValueClass.isValueObjectCompatible(arg),
67 () -> classification + ": " + arg.getTypeName());
68 }
69
70 @Test
71 void testIsConcreteValueClass() {
72 isConcreteValueClassCase(false, int.class, "primitive");
73 isConcreteValueClassCase(false, Object.class, "Object");
74 isConcreteValueClassCase(false, Number.class, "abstract value class");
75 isConcreteValueClassCase(true, Integer.class, "final value class");
76 isConcreteValueClassCase(false, ClassValue.class, "abstract identity class");
77 isConcreteValueClassCase(false, ArrayList.class, "identity class");
78 isConcreteValueClassCase(false, String.class, "final identity class");
79 isConcreteValueClassCase(false, Comparable.class, "interface");
80 isConcreteValueClassCase(false, int[].class, "array class");
81 isConcreteValueClassCase(false, Object[].class, "array class");
82 isConcreteValueClassCase(false, Number[].class, "array class");
83 isConcreteValueClassCase(false, Integer[].class, "array class");
84 isConcreteValueClassCase(false, ClassValue[].class, "array class");
85 isConcreteValueClassCase(false, ArrayList[].class, "array class");
86 isConcreteValueClassCase(false, String[].class, "array class");
87 isConcreteValueClassCase(false, Comparable[].class, "array class");
88 }
89
90 private static void isConcreteValueClassCase(boolean expected, Class<?> arg, String classification) {
91 assertEquals(PreviewFeatures.isEnabled() && expected,
92 ValueClass.isConcreteValueClass(arg),
93 () -> classification + ": " + arg.getTypeName());
94 }
95
96 @Test
97 void testBinaryPayload() {
98 // Actual value class cases are tested in ValueClassPreviewTest
99 assertTrue(ValueClass.hasBinaryPayload(int.class), "primitive");
100 binaryPayloadCase(false, Object.class, "Object");
101 binaryPayloadCase(false, Number.class, "abstract value class");
102 binaryPayloadCase(true, Integer.class, "final value class (wrapper)");
103 binaryPayloadCase(false, Optional.class, "final value class (reference)");
104 binaryPayloadCase(false, ClassValue.class, "abstract identity class");
105 binaryPayloadCase(false, ArrayList.class, "identity class");
106 binaryPayloadCase(false, String.class, "final identity class");
107 binaryPayloadCase(false, Comparable.class, "interface");
108 binaryPayloadCase(false, int[].class, "array class");
109 binaryPayloadCase(false, Object[].class, "array class");
110 binaryPayloadCase(false, Number[].class, "array class");
111 binaryPayloadCase(false, Integer[].class, "array class");
112 binaryPayloadCase(false, ClassValue[].class, "array class");
113 binaryPayloadCase(false, ArrayList[].class, "array class");
114 binaryPayloadCase(false, String[].class, "array class");
115 binaryPayloadCase(false, Comparable[].class, "array class");
116 }
117
118 private static void binaryPayloadCase(boolean expected, Class<?> arg, String classification) {
119 assertEquals(PreviewFeatures.isEnabled() && expected,
120 ValueClass.hasBinaryPayload(arg),
121 () -> classification + ": " + arg.getTypeName());
122 }
123 }