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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.internal.value; 27 28 import jdk.internal.access.JavaLangAccess; 29 import jdk.internal.access.SharedSecrets; 30 import jdk.internal.vm.annotation.IntrinsicCandidate; 31 32 import java.lang.constant.ClassDesc; 33 34 /** 35 * Utilities to access Primitive Classes as described in JEP 401. 36 */ 37 public class PrimitiveClass { 38 39 /** 40 * ACC_PRIMITIVE modifier defined by JEP 401. Subject to change. 41 */ 42 public static final int PRIMITIVE_CLASS = 0x00000800; 43 44 private static final JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess(); 45 46 47 /** 48 * Returns a {@code Class} object representing the primary type 49 * of this class or interface. 50 * <p> 51 * If this {@code Class} object represents a primitive type or an array type, 52 * then this method returns this class. 53 * <p> 54 * If this {@code Class} object represents a {@linkplain #isPrimitiveClass(Class) 55 * primitive class}, then this method returns the <em>primitive reference type</em> 56 * type of this primitive class. 57 * <p> 58 * Otherwise, this {@code Class} object represents a non-primitive class or interface 59 * and this method returns this class. 60 * 61 * @param aClass a class 62 * @return the {@code Class} representing the primary type of 63 * this class or interface 64 * @since Valhalla 65 */ 66 @IntrinsicCandidate 67 public static Class<?> asPrimaryType(Class<?> aClass) { 68 return javaLangAccess.asPrimaryType(aClass); 69 } 70 71 /** 72 * Returns a {@code Class} object representing the <em>primitive value type</em> 73 * of this class if this class is a {@linkplain #isPrimitiveClass(Class)} primitive class}. 74 * 75 * @apiNote Alternatively, this method returns null if this class is not 76 * a primitive class rather than throwing UOE. 77 * 78 * @param aClass a class 79 * @return the {@code Class} representing the {@linkplain #isPrimitiveValueType(Class) 80 * primitive value type} of this class if this class is a primitive class 81 * @throws UnsupportedOperationException if this class or interface 82 * is not a primitive class 83 * @since Valhalla 84 */ 85 @SuppressWarnings("unchecked") 86 @IntrinsicCandidate 87 public static Class<?> asValueType(Class<?> aClass) { 88 return javaLangAccess.asValueType(aClass); 89 } 90 91 /** 92 * Returns {@code true} if this {@code Class} object represents the primary type 93 * of this class or interface. 94 * <p> 95 * If this {@code Class} object represents a primitive type or an array type, 96 * then this method returns {@code true}. 97 * <p> 98 * If this {@code Class} object represents a {@linkplain #isPrimitiveClass(Class) 99 * primitive}, then this method returns {@code true} if this {@code Class} 100 * object represents a primitive reference type, or returns {@code false} 101 * if this {@code Class} object represents a primitive value type. 102 * <p> 103 * If this {@code Class} object represents a non-primitive class or interface, 104 * then this method returns {@code true}. 105 * 106 * @param aClass a class 107 * @return {@code true} if this {@code Class} object represents 108 * the primary type of this class or interface 109 * @since Valhalla 110 */ 111 public static boolean isPrimaryType(Class<?> aClass) { 112 return javaLangAccess.isPrimaryType(aClass); 113 } 114 115 /** 116 * Returns {@code true} if this {@code Class} object represents 117 * a {@linkplain #isPrimitiveClass(Class) primitive} value type. 118 * 119 * @return {@code true} if this {@code Class} object represents 120 * the value type of a primitive class 121 * @since Valhalla 122 */ 123 public static boolean isPrimitiveValueType(Class<?> aClass) { 124 return javaLangAccess.isPrimitiveValueType(aClass); 125 } 126 127 /** 128 * Returns {@code true} if this class is a primitive class. 129 * <p> 130 * Each primitive class has a {@linkplain #isPrimaryType(Class) primary type} 131 * representing the <em>primitive reference type</em> and a 132 * {@linkplain #isPrimitiveValueType(Class) secondary type} representing 133 * the <em>primitive value type</em>. The primitive reference type 134 * and primitive value type can be obtained by calling the 135 * {@link #asPrimaryType(Class)} and {@link PrimitiveClass#asValueType} method 136 * of a primitive class respectively. 137 * <p> 138 * A primitive class is a {@linkplain Class#isValue() value class}. 139 * 140 * @param aClass a class 141 * @return {@code true} if this class is a primitive class, otherwise {@code false} 142 * @see Class#isValue() 143 * @see #asPrimaryType(Class) 144 * @see #asValueType(Class) 145 * @since Valhalla 146 */ 147 public static boolean isPrimitiveClass(Class<?> aClass) { 148 return javaLangAccess.isPrimitiveClass(aClass); 149 } 150 151 /** 152 * Returns whether this {@linkplain ClassDesc} describes a 153 * {@linkplain #isPrimitiveValueType(Class)} primitive value type}. 154 * 155 * @return whether this {@linkplain ClassDesc} describes a primitive value type. 156 * @since Valhalla 157 */ 158 public static boolean isPrimitiveValueClassDesc(ClassDesc classDesc) { 159 return classDesc.descriptorString().startsWith("Q"); 160 } 161 }