Hello, while using java.lang.Integer.TYPE I've found out that currently wrapper classes for primitives initialize their own TYPE-fields by calling native method java.lang.Class.getPrimitiveClass().
This can be simplified by changing existing declaration (here for java.lang.Integer) @SuppressWarnings("unchecked") public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); to public static final Class<Integer> TYPE = int.class; This is likely to improve start-up time as Class.getPrimitiveClass() is called 9 times (8 primitive type wrappers + java.lang.Void), after the change this method is not called at all and thus can be removed along with its backing C++ code on VM-side. The fields are initialized purely on Java side. I've verified correctness of the substitution with this test run on JDK 11 @Test void name() { assert void.class == Void.TYPE; assert boolean.class == Boolean.TYPE; assert byte.class == Byte.TYPE; assert char.class == Character.TYPE; assert short.class == Short.TYPE; assert int.class == Integer.TYPE; assert long.class == Long.TYPE; assert float.class == Float.TYPE; assert double.class == Double.TYPE; } The patch is attached. Regards, Sergey Tsypanov
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -340,14 +340,6 @@ /* - * Find primitive classes - * utf: class name - */ -JNIEXPORT jclass JNICALL -JVM_FindPrimitiveClass(JNIEnv *env, const char *utf); - - -/* * Find a class from a boot class loader. Returns NULL if class not found. */ JNIEXPORT jclass JNICALL diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -782,22 +782,6 @@ return NULL; JVM_END - -JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf)) - JVMWrapper("JVM_FindPrimitiveClass"); - oop mirror = NULL; - BasicType t = name2type(utf); - if (t != T_ILLEGAL && !is_reference_type(t)) { - mirror = Universe::java_mirror(t); - } - if (mirror == NULL) { - THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf); - } else { - return (jclass) JNIHandles::make_local(env, mirror); - } -JVM_END - - // Returns a class loaded by the bootstrap class loader; or null // if not found. ClassNotFoundException is not thrown. // FindClassFromBootLoader is exported to the launcher for windows. diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java --- a/src/java.base/share/classes/java/lang/Boolean.java +++ b/src/java.base/share/classes/java/lang/Boolean.java @@ -62,8 +62,7 @@ * * @since 1.1 */ - @SuppressWarnings("unchecked") - public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean"); + public static final Class<Boolean> TYPE = boolean.class; /** * The value of the Boolean. diff --git a/src/java.base/share/classes/java/lang/Byte.java b/src/java.base/share/classes/java/lang/Byte.java --- a/src/java.base/share/classes/java/lang/Byte.java +++ b/src/java.base/share/classes/java/lang/Byte.java @@ -62,8 +62,7 @@ * The {@code Class} instance representing the primitive type * {@code byte}. */ - @SuppressWarnings("unchecked") - public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte"); + public static final Class<Byte> TYPE = byte.class; /** * Returns a new {@code String} object representing the diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -173,8 +173,7 @@ * * @since 1.1 */ - @SuppressWarnings("unchecked") - public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char"); + public static final Class<Character> TYPE = char.class; /* * Normative general types diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -2828,12 +2828,6 @@ private native java.security.ProtectionDomain getProtectionDomain0(); /* - * Return the Virtual Machine's Class object for the named - * primitive type. - */ - static native Class<?> getPrimitiveClass(String name); - - /* * Check if client is allowed to access members. If access is denied, * throw a SecurityException. * diff --git a/src/java.base/share/classes/java/lang/Double.java b/src/java.base/share/classes/java/lang/Double.java --- a/src/java.base/share/classes/java/lang/Double.java +++ b/src/java.base/share/classes/java/lang/Double.java @@ -141,8 +141,7 @@ * * @since 1.1 */ - @SuppressWarnings("unchecked") - public static final Class<Double> TYPE = (Class<Double>) Class.getPrimitiveClass("double"); + public static final Class<Double> TYPE = double.class; /** * Returns a string representation of the {@code double} diff --git a/src/java.base/share/classes/java/lang/Float.java b/src/java.base/share/classes/java/lang/Float.java --- a/src/java.base/share/classes/java/lang/Float.java +++ b/src/java.base/share/classes/java/lang/Float.java @@ -138,8 +138,7 @@ * * @since 1.1 */ - @SuppressWarnings("unchecked") - public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float"); + public static final Class<Float> TYPE = float.class; /** * Returns a string representation of the {@code float} diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java --- a/src/java.base/share/classes/java/lang/Integer.java +++ b/src/java.base/share/classes/java/lang/Integer.java @@ -81,8 +81,7 @@ * * @since 1.1 */ - @SuppressWarnings("unchecked") - public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); + public static final Class<Integer> TYPE = int.class; /** * All possible chars for representing a number as a String diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java --- a/src/java.base/share/classes/java/lang/Long.java +++ b/src/java.base/share/classes/java/lang/Long.java @@ -82,8 +82,7 @@ * * @since 1.1 */ - @SuppressWarnings("unchecked") - public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long"); + public static final Class<Long> TYPE = long.class; /** * Returns a string representation of the first argument in the diff --git a/src/java.base/share/classes/java/lang/Short.java b/src/java.base/share/classes/java/lang/Short.java --- a/src/java.base/share/classes/java/lang/Short.java +++ b/src/java.base/share/classes/java/lang/Short.java @@ -61,8 +61,7 @@ * The {@code Class} instance representing the primitive type * {@code short}. */ - @SuppressWarnings("unchecked") - public static final Class<Short> TYPE = (Class<Short>) Class.getPrimitiveClass("short"); + public static final Class<Short> TYPE = short.class; /** * Returns a new {@code String} object representing the diff --git a/src/java.base/share/classes/java/lang/Void.java b/src/java.base/share/classes/java/lang/Void.java --- a/src/java.base/share/classes/java/lang/Void.java +++ b/src/java.base/share/classes/java/lang/Void.java @@ -40,8 +40,7 @@ * The {@code Class} object representing the pseudo-type corresponding to * the keyword {@code void}. */ - @SuppressWarnings("unchecked") - public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void"); + public static final Class<Void> TYPE = void.class; /* * The Void class cannot be instantiated. diff --git a/src/java.base/share/native/libjava/Class.c b/src/java.base/share/native/libjava/Class.c --- a/src/java.base/share/native/libjava/Class.c +++ b/src/java.base/share/native/libjava/Class.c @@ -158,27 +158,3 @@ } return (*env)->IsAssignableFrom(env, cls2, cls); } - -JNIEXPORT jclass JNICALL -Java_java_lang_Class_getPrimitiveClass(JNIEnv *env, - jclass cls, - jstring name) -{ - const char *utfName; - jclass result; - - if (name == NULL) { - JNU_ThrowNullPointerException(env, 0); - return NULL; - } - - utfName = (*env)->GetStringUTFChars(env, name, 0); - if (utfName == 0) - return NULL; - - result = JVM_FindPrimitiveClass(env, utfName); - - (*env)->ReleaseStringUTFChars(env, name, utfName); - - return result; -}