All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.progrm_jarvis.javacommons.classloading.extension.LegacyClassExtensions Maven / Gradle / Ivy

package ru.progrm_jarvis.javacommons.classloading.extension;

import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.val;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Array;

import static java.lang.invoke.MethodType.methodType;

/**
 * Extensions to provide new {@link Class} methods on older Java versions.
 */
@UtilityClass
public class LegacyClassExtensions {

    /**
     * Method handle referring to {@link Class}{@code .arrayType()} method
     */
    private final @Nullable MethodHandle ARRAY_TYPE__METHOD_HANDLE;

    static {
        val lookup = MethodHandles.publicLookup();
        MethodHandle methodHandle;
        try {
            methodHandle = lookup.findVirtual(Class.class, "arrayType", methodType(Class.class));
        } catch (NoSuchMethodException | IllegalAccessException e) {
            methodHandle = null;
        }
        ARRAY_TYPE__METHOD_HANDLE = methodHandle;
    }

    /**
     * Gets the class-object corresponding to an array of elements of the given type.
     *
     * @param elementType class-object of array elements
     * @param  type of array elements
     * @return array-type of the specified type
     *
     * @apiNote this method is available on {@link Class} itself since Java 12
     */
    @SneakyThrows // call to `MethodHandle#invokeExact(...)`
    public static  @NotNull Class arrayType(final @NotNull Class elementType) {
        return uncheckedArrayClassCast(ARRAY_TYPE__METHOD_HANDLE == null
                ? Array.newInstance(elementType, 0).getClass() // this is considered the standard implementation
                : (Class) ARRAY_TYPE__METHOD_HANDLE.invokeExact(elementType)
        );
    }

    /**
     * Casts the given array-class object into the specific one.
     *
     * @param type raw-typed array-class object
     * @param  exact wanted type of array-class object
     * @return the provided array-class object with its type case to the specific one
     *
     * @apiNote this is effectively no-op
     */
    // note: no nullability annotations are present on parameter and return type as cast of `null` is also safe
    @Contract("_ -> param1")
    @SuppressWarnings("unchecked")
    private  Class uncheckedArrayClassCast(final Class type) {
        return (Class) type;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy