1 /* 2 * Copyright (c) 2022, 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 import jdk.internal.misc.PreviewFeatures; 25 26 import java.lang.reflect.Modifier; 27 import java.lang.annotation.*; 28 29 /* 30 * @test 31 * @bug 8296743 32 * @modules java.base/jdk.internal.misc 33 * @summary Verify array classes and primitives have expected modifiers 34 * @run main/othervm TestPrimitiveAndArrayModifiers 35 * @run main/othervm --enable-preview TestPrimitiveAndArrayModifiers 36 */ 37 @ExpectedModifiers(Modifier.PUBLIC | Modifier.FINAL | Modifier.ABSTRACT) 38 public class TestPrimitiveAndArrayModifiers { 39 40 /* 41 * Relevant excerpt of the Class.getModifiers() specification: 42 * <p> If the underlying class is an array class: 43 * <ul> 44 * <li> its {@code public}, {@code private} and {@code protected} 45 * modifiers are the same as those of its component type 46 * <li> its {@code final} and {@code abstract} modifiers are always 47 * {@code true} 48 * <li> its interface modifier is always {@code false}, even when 49 * the component type is an interface 50 * </ul> 51 */ 52 53 public static void main(String... args) throws Exception { 54 testPrimitives(); 55 testArrays(); 56 } 57 58 private static void testArrays() { 59 Class<?>[] testCases = { 60 TestPrimitiveAndArrayModifiers.class, 61 62 PackagePrivateClass.class, 63 ProtectedClass.class, 64 PrivateClass.class, 65 66 PublicInterface.class, 67 PackagePrivateInterface.class, 68 ProtectedInterface.class, 69 PrivateInterface.class, 70 }; 71 72 for(var testCase : testCases) { 73 int expectedModifiers = 74 testCase.getAnnotation(ExpectedModifiers.class).value(); 75 if (PreviewFeatures.isEnabled()) { 76 // All arrays under preview also have IDENTITY 77 expectedModifiers |= Modifier.IDENTITY; 78 } 79 Class<?> arrayClass = testCase.arrayType(); 80 int actualModifiers = arrayClass.getModifiers(); 81 if (expectedModifiers != actualModifiers) { 82 throw new RuntimeException("Expected " + Modifier.toString(expectedModifiers) + 83 " on " + testCase.getCanonicalName() + 84 ", but got " + Modifier.toString(actualModifiers)); 85 } 86 } 87 } 88 89 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT) 90 class PackagePrivateClass {} 91 92 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PROTECTED) 93 protected class ProtectedClass {} 94 95 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PRIVATE) 96 private class PrivateClass {} 97 98 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PUBLIC) 99 public interface PublicInterface {} 100 101 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT) 102 interface PackagePrivateInterface {} 103 104 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PROTECTED) 105 protected interface ProtectedInterface {} 106 107 @ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PRIVATE) 108 private interface PrivateInterface {} 109 110 /* 111 * Relevant excerpt of the Class.getModifiers() specification: 112 * 113 * If this {@code Class} object represents a primitive type or 114 * void, its {@code public}, {@code abstract}, and {@code final} 115 * modifiers are always {@code true}. 116 */ 117 private static void testPrimitives() { 118 Class<?>[] testCases = { 119 void.class, 120 boolean.class, 121 byte.class, 122 short.class, 123 char.class, 124 int.class, 125 float.class, 126 long.class, 127 double.class, 128 }; 129 130 for(var testCase : testCases) { 131 int actualModifiers = testCase.getModifiers(); 132 if ((Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.FINAL) != 133 actualModifiers) { 134 throw new RuntimeException("Bad modifiers " + 135 Modifier.toString(actualModifiers) + 136 " on primitive type " + testCase); 137 } 138 } 139 } 140 } 141 142 @Retention(RetentionPolicy.RUNTIME) 143 @interface ExpectedModifiers { 144 int value() default 0; 145 }