
org.cp.elements.lang.ClassUtils Maven / Gradle / Ivy
/*
* Copyright 2016 Author or Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cp.elements.lang;
import static org.cp.elements.util.stream.StreamUtils.stream;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.cp.elements.lang.reflect.ConstructorNotFoundException;
import org.cp.elements.lang.reflect.FieldNotFoundException;
import org.cp.elements.lang.reflect.MethodNotFoundException;
import org.cp.elements.lang.reflect.ModifierUtils;
import org.cp.elements.util.ArrayUtils;
/**
* {@link ClassUtils} is an abstract class providing utility methods for working with {@link Class} objects.
*
* @author John J. Blum
* @see java.lang.Class
* @see java.lang.Object
* @see java.lang.annotation.Annotation
* @see java.lang.reflect.AnnotatedElement
* @see java.lang.reflect.Constructor
* @see java.lang.reflect.Field
* @see java.lang.reflect.Method
* @see java.net.URL
* @since 1.0.0
*/
@SuppressWarnings("unused")
public abstract class ClassUtils {
protected static final boolean DEFAULT_INITIALIZE_LOADED_CLASS = true;
public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
public static final String CLASS_FILE_EXTENSION = ".class";
public static final String CLONE_METHOD_NAME = "clone";
public static final String MAIN_METHOD_NAME = "main";
/**
* Determines whether a given Class type is assignable to a declared Class type. A given Class type is assignable to
* a declared Class type if it is in the same Class type hierarchy, i.e. the given Class type is a subclass,
* or sub-interface of the declared Class type. Null is also assignable to the declared (to) Class type.
*
* @param fromType the Class type evaluated for assignment compatibility with the declared Class type.
* @param toType the declared Class type defining the type hierarchy, or bounds on the given Class type for
* assignment compatibility.
* @return a boolean value indicating given Class type is assignable to the declared Class type.
* @see java.lang.Class#isAssignableFrom(Class)
*/
@NullSafe
public static boolean assignableTo(Class> fromType, Class> toType) {
return (toType != null && (fromType == null || toType.isAssignableFrom(fromType)));
}
/**
* Get the Class type of the specified Object. Returns null if the Object reference is null.
*
* @param obj the Object who's Class type is being determined.
* @return a Class object signifying the type of the specified Object.
* @see java.lang.Object#getClass()
*/
@NullSafe
public static Class> getClass(Object obj) {
return (obj != null ? obj.getClass() : null);
}
/**
* Gets the fully-qualified name of the Class type for the specified Object. Returns null if the Object reference
* is null.
*
* @param obj the Object who's class name is determined.
* @return a String value specifying the fully qualified class name of the Object.
* @see java.lang.Class#getName()
* @see java.lang.Object#getClass()
*/
@NullSafe
public static String getClassName(Object obj) {
return (obj != null ? obj.getClass().getName() : null);
}
/**
* Gets the unqualified, simple name of the Class type for the specified Object. Returns null if the Object reference
* is null.
*
* @param obj the Object who's simple class name is determined.
* @return a String value indicating the simple class name of the Object.
* @see java.lang.Class#getSimpleName()
* @see java.lang.Object#getClass()
*/
@NullSafe
public static String getClassSimpleName(Object obj) {
return (obj != null ? obj.getClass().getSimpleName() : null);
}
/**
* Determines all the interfaces implemented by the given object's {@link Class} type.
*
* This method performs a deep analysis of the object's {@link Class} along with all interfaces
* implemented by the object's {@link Class superclass}, up the {@link Class} hierarchy until
* the {@link Object} class is reached.
*
* @param obj {@link Object} to evaluate.
* @return all interfaces implemented by the given object's {@link Class} and its {@link Class superclass}.
* Returns an empty {@link Set} if the given {@link Object} does not implement any interfaces.
* @see #getInterfaces(Class)
* @see #getClass(Object)
* @see java.lang.Object
*/
@NullSafe
public static Set> getInterfaces(Object obj) {
return getInterfaces(getClass(obj));
}
/**
* Determines all the interfaces implemented by the given {@link Class} type.
*
* This method performs a deep analysis of all the interfaces implemented by the given {@link Class} type
* along with interfaces implemented by the {@link Class Class's} {@link Class superclass},
* up the {@link Class} hierarchy until the {@link Object} class is reached.
*
* @param type {@link Class} to evaluate.
* @return all interfaces implemented by the given {@link Class} and its superclass.
* Returns an empty {@link Set} if the given {@link Class} does not implement any interfaces.
* @see #getInterfaces(Class, Set)
* @see java.lang.Class
*/
@NullSafe
public static Set> getInterfaces(Class type) {
return Optional.ofNullable(type).map(theType -> getInterfaces(type, new HashSet<>()))
.orElse(Collections.emptySet());
}
/**
* Determines all the interfaces implemented by the given {@link Class} type.
*
* This method performs a deep analysis of all the interfaces implemented by the given {@link Class} type
* along with interfaces implemented by the {@link Class Class's} {@link Class superclass},
* up the {@link Class} hierarchy until the {@link Object} class is reached.
*
* @param type {@link Class} to evaluate.
* @param interfaces {@link Set} containing all the {@link Class interfaces} implemented by
* the given {@link Class} type.
* @return all interfaces implemented by the given {@link Class} and its superclass.
* Returns an empty {@link Set} if the given {@link Class} does not implement any interfaces.
* @see java.lang.Class
*/
private static Set> getInterfaces(Class type, Set> interfaces) {
if (type.getSuperclass() != null) {
getInterfaces(type.getSuperclass(), interfaces);
}
for (Class> implementedType : type.getInterfaces()) {
if (!interfaces.contains(implementedType)) {
interfaces.add(implementedType);
getInterfaces(implementedType, interfaces);
}
}
return interfaces;
}
/**
* Attempts to find a compatible constructor on the given class type with a signature having parameter types
* satisfying the specified arguments.
*
* @param the generic class type to search for the constructor.
* @param type the Class type to search for the desired constructor.
* @param arguments an array of Object arguments used to match the constructor's signature.
* @return a Constructor from the given class type whose signature matches the specified arguments.
* @see java.lang.Class
* @see java.lang.Class#getDeclaredConstructors()
* @see java.lang.reflect.Constructor
*/
@SuppressWarnings({ "unchecked", "all" })
public static Constructor findConstructor(Class type, Object... arguments) {
for (Constructor> constructor : type.getDeclaredConstructors()) {
Class>[] parameterTypes = constructor.getParameterTypes();
if (ArrayUtils.nullSafeLength(arguments) == parameterTypes.length) {
boolean match = true;
for (int index = 0; match && index < parameterTypes.length; index++) {
match &= instanceOf(arguments[index], parameterTypes[index]);
}
if (match) {
return (Constructor) constructor;
}
}
}
return null;
}
/**
* Gets the constructor with the specified signature from the given class type.
*
* @param the generic class type from which to get the constructor.
* @param type the Class type from which to get the Constructor.
* @param parameterTypes an array of class types indicating the constructor signature.
* @return a Constructor from the given class type with a matching signature.
* @see java.lang.Class
* @see java.lang.Class#getDeclaredConstructor(Class[])
* @see java.lang.reflect.Constructor
*/
public static Constructor getConstructor(Class type, Class>... parameterTypes) {
try {
return type.getDeclaredConstructor(parameterTypes);
}
catch (NoSuchMethodException e) {
throw new ConstructorNotFoundException(e);
}
}
/**
* Attempts to resolve the constructor from the given class type based on the constructor's exact signature,
* otherwise finds a constructor who's signature parameter types satisfy the array of Object arguments.
*
* @param the generic class type from which to resolve the constructor.
* @param type the Class type from which to resolve the constructor.
* @param parameterTypes an array of Class types indicating the desired constructor's signature.
* @param arguments an array of Object arguments used to match the constructor's signature.
* @return a Constructor from the given class type who's signature either matches the parameter types
* or satisfies the array of arguments.
* @see #getConstructor(Class, Class[])
* @see #findConstructor(Class, Object...)
* @see java.lang.Class
* @see java.lang.reflect.Constructor
*/
public static Constructor resolveConstructor(Class type, Class>[] parameterTypes, Object... arguments) {
try {
return getConstructor(type, parameterTypes);
}
catch (ConstructorNotFoundException e) {
Constructor constructor = findConstructor(type, arguments);
Assert.notNull(constructor, new ConstructorNotFoundException(String.format(
"Failed to resolve constructor with signature [%1$s] on class type [%2$s]",
getMethodSignature(getSimpleName(type), parameterTypes, Void.class), getName(type)), e.getCause()));
return constructor;
}
}
/**
* Gets a Field object representing the named field on the specified class. This method will recursively search
* up the class hierarchy of the specified class until the Object class is reached. If the named field is found
* then a Field object representing the class field is returned, otherwise a NoSuchFieldException is thrown.
*
* @param type the Class type to search for the specified field.
* @param fieldName a String indicating the name of the field on the class.
* @return a Field object representing the named field on the specified class.
* @throws FieldNotFoundException if the named field does not exist on the specified class
* or a superclass of the specified class.
* @see java.lang.Class
* @see java.lang.Class#getDeclaredField(String)
* @see java.lang.reflect.Field
*/
public static Field getField(Class> type, String fieldName) {
try {
return type.getDeclaredField(fieldName);
}
catch (NoSuchFieldException e) {
if (type.getSuperclass() != null) {
return getField(type.getSuperclass(), fieldName);
}
throw new FieldNotFoundException(e);
}
}
/**
* Attempts to find a method with the specified name on the given class type having a signature with parameter types
* that are compatible with the given arguments. This method searches recursively up the inherited class hierarchy
* for the given class type until the desired method is found or the class type hierarchy is exhausted, in which case,
* null is returned.
*
* @param type the Class type to search for the desired method.
* @param methodName a String value indicating the name of the method to find.
* @param arguments an array of object values indicating the arguments the method's parameters must accept.
* @return a Method on the given class type with the specified name having a signature compatible with the arguments,
* or null if no such Method exists on the given class type or one of it's inherited (parent) class types.
* @throws NullPointerException if the given class type is null.
* @see java.lang.Class
* @see java.lang.Class#getDeclaredMethods()
* @see java.lang.Class#getSuperclass()
* @see java.lang.reflect.Method
*/
@SuppressWarnings("all")
public static Method findMethod(Class> type, String methodName, Object... arguments) {
for (Method method : type.getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
Class>[] parameterTypes = method.getParameterTypes();
if (ArrayUtils.nullSafeLength(arguments) == parameterTypes.length) {
boolean match = true;
for (int index = 0; match && index < parameterTypes.length; index++) {
match &= instanceOf(arguments[index], parameterTypes[index]);
}
if (match) {
return method;
}
}
}
}
return (type.getSuperclass() != null ? findMethod(type.getSuperclass(), methodName, arguments) : null);
}
/**
* Gets a Method object representing the named method on the specified class. This method will recursively search
* up the class hierarchy of the specified class until the Object class is reached. If the named method is found
* then a Method object representing the class method is returned, otherwise a NoSuchMethodException is thrown.
*
* @param type the Class type to search for the specified method.
* @param methodName a String indicating the name of the method on the class.
* @param parameterTypes an array of Class objects identifying the parameters and their types
* based on the method's signature.
* @return a Method object representing the named method on the specified class.
* @throws MethodNotFoundException if the named method does not exist on the specified class
* or a superclass of the specified class.
* @see java.lang.Class
* @see java.lang.Class#getDeclaredMethod(String, Class[])
* @see java.lang.reflect.Method
*/
public static Method getMethod(Class> type, String methodName, Class>... parameterTypes) {
try {
return type.getDeclaredMethod(methodName, parameterTypes);
}
catch (NoSuchMethodException e) {
if (type.getSuperclass() != null) {
return getMethod(type.getSuperclass(), methodName, parameterTypes);
}
throw new MethodNotFoundException(e);
}
}
/**
* Attempts to resolve the method with the specified name and signature on the given class type. The named method's
* resolution is first attempted by using the specified method's name along with the array of parameter types.
* If unsuccessful, the method proceeds to lookup the named method by searching all "declared" methods
* of the class type having a signature compatible with the given argument types. This method operates recursively
* until the method is resolved or the class type hierarchy is exhausted, in which case,
* a MethodNotFoundException is thrown.
*
* @param type the Class type on which to resolve the method.
* @param methodName a String indicating the name of the method to resolve.
* @param parameterTypes an array of Class objects used to resolve the exact signature of the method.
* @param arguments an array of Objects used in a method invocation serving as a fallback search/lookup strategy
* if the method cannot be resolved using it's parameter types. Maybe null.
* @param returnType the declared class type of the method's return value (used only for Exception message purposes).
* @return the resolved method from the given class type given the name, parameter types (signature)
* and calling arguments, if any.
* @throws MethodNotFoundException if the specified method cannot be resolved on the given class type.
* @throws NullPointerException if the class type is null.
* @see #getMethod(Class, String, Class[])
* @see #findMethod(Class, String, Object...)
* @see java.lang.Class
* @see java.lang.reflect.Method
*/
public static Method resolveMethod(Class> type, String methodName, Class>[] parameterTypes, Object[] arguments,
Class> returnType) {
try {
return getMethod(type, methodName, parameterTypes);
}
catch (MethodNotFoundException e) {
Method method = findMethod(type, methodName, arguments);
Assert.notNull(method, new MethodNotFoundException(String.format(
"Failed to resolve method with signature [%1$s] on class type [%2$s]",
getMethodSignature(methodName, parameterTypes, returnType), getName(type)), e.getCause()));
return method;
}
}
/**
* Builds the signature of a method based on a java.lang.reflect.Method object.
*
* @param method the Method object to build an method signature of.
* @return the signature of the Method as a String.
* @see #getMethodSignature(String, Class[], Class)
*/
protected static String getMethodSignature(Method method) {
return getMethodSignature(method.getName(), method.getParameterTypes(), method.getReturnType());
}
/**
* Builds the signature of a method based on the method's name, parameter types and return type.
*
* @param methodName a String indicating the name of the method.
* @param parameterTypes an array of Class objects indicating the type of each method parameter.
* @param returnType a Class object indicating the methods return type.
* @return the signature of the method as a String.
* @see #getSimpleName(Class)
*/
protected static String getMethodSignature(String methodName, Class>[] parameterTypes, Class> returnType) {
StringBuilder buffer = new StringBuilder(methodName);
buffer.append("(");
if (parameterTypes != null) {
int index = 0;
for (Class> parameterType : parameterTypes) {
buffer.append(index++ > 0 ? ", :" : ":");
buffer.append(getSimpleName(parameterType));
}
}
buffer.append("):");
buffer.append(returnType == null || Void.class.equals(returnType) ? "void" : getSimpleName(returnType));
return buffer.toString();
}
/**
* Gets the fully-qualified name of the Class.
*
* @param type the Class type to return the fully-qualified name of.
* @return a String value with the fully-qualified name of the Class.
* @see java.lang.Class#getName()
*/
@NullSafe
public static String getName(Class type) {
return (type != null ? type.getName() : null);
}
/**
* Gets the resource name of the given {@link Class} type. The resource name of a given {@link Class} is
* the pathname of the class file defining the {@link Class} type relative to the CLASSPATH.
*
* For instance, if the {@link Class} type were java.lang.Object.class, then the resource name would be...
*
*
* java/lang/Object.class.
*
*
* @param type the {@link Class} type from which to construct the resource name.
* @return a String indicating the resource name of the given {@link Class} type.
* @see java.lang.Class
*/
@NullSafe
public static String getResourceName(Class type) {
return (type != null ? type.getName().replaceAll("\\.", "/").concat(CLASS_FILE_EXTENSION) : null);
}
/**
* Gets the simple name of the Class.
*
* @param type the Class type to return the simple name of.
* @return a String value with the simple name of the Class.
* @see java.lang.Class#getSimpleName()
*/
@NullSafe
public static String getSimpleName(Class type) {
return (type != null ? type.getSimpleName() : null);
}
/**
* Determines whether the given {@link Class} has a {@literal main} {@link Method}.
*
* @param type {@link Class} to evaluate.
* @return a boolean value indicating whether the given {@link Class} has a {@literal main} {@link Method}.
* @see java.lang.Class#getDeclaredMethods()
* @see #isMainMethod(Method)
* @see java.lang.Class
*/
@NullSafe
public static boolean hasMainMethod(Class type) {
return Optional.ofNullable(type).map(theType -> type.getDeclaredMethods())
.map(methods -> stream(methods).anyMatch(ClassUtils::isMainMethod)).orElse(false);
}
/**
* Determines whether the given {@link Object} implements any {@link Class interfaces}.
*
* @param obj {@link Object} to evaluate.
* @return a boolean value indicating whether the given {@link Object} implements any {@link Class interfaces}.
* @see #getInterfaces(Object)
* @see java.lang.Object
*/
@NullSafe
public static boolean implementsInterfaces(Object obj) {
return !getInterfaces(obj).isEmpty();
}
/**
* Determines whether the given {@link Class} type implements any {@link Class interfaces}.
*
* @param type {@link Class} type to evaluate.
* @return a boolean value indicating whether the given {@link Class} type implements any {@link Class interfaces}.
* @see #getInterfaces(Class)
* @see java.lang.Class
*/
@NullSafe
public static boolean implementsInterfaces(Class type) {
return !getInterfaces(type).isEmpty();
}
/**
* Determines whether the given Object is an instance of the specified Class. Note, an Object cannot be an
* instance of null, so this method returns false if the Class type is null or the Object is null.
*
* @param obj the Object to test as an instance of the specified Class type.
* @param type the Class type used in the instanceof operation.
* @return a boolean value indicating whether the Object is an instance of the Class type.
* @see java.lang.Class#isInstance(Object)
*/
@NullSafe
public static boolean instanceOf(Object obj, Class> type) {
return (type != null && type.isInstance(obj));
}
/**
* Determines whether the specified Class object represents an annotation type.
*
* @param type the Class object tested as an annotation type.
* @return true iff the Class object is not null and represents an annotation type.
* @see java.lang.Class#isAnnotation()
*/
@NullSafe
public static boolean isAnnotation(Class type) {
return (type != null && type.isAnnotation());
}
/**
* Determines whether the specified Annotation meta-data is present on the given "annotated" members,
* such as fields and methods.
*
* @param annotation the Annotation used in the detection for presence on the given members.
* @param members the members of a class type or object to inspect for the presence of the specified Annotation.
* @return a boolean value indicating whether the specified Annotation is present on any of the given members.
* @see java.lang.annotation.Annotation
* @see java.lang.reflect.AccessibleObject#isAnnotationPresent(Class)
*/
@NullSafe
public static boolean isAnnotationPresent(Class extends Annotation> annotation, AnnotatedElement... members) {
return stream(ArrayUtils.nullSafeArray(members, AnnotatedElement.class))
.anyMatch(member -> member != null && member.isAnnotationPresent(annotation));
}
/**
* Determines whether the specified Class object represents an array type.
*
* @param type the Class object tested as an array type.
* @return true iff the Class object is not null and represents an array type.
* @see java.lang.Class#isArray()
*/
@NullSafe
public static boolean isArray(Class type) {
return (type != null && type.isArray());
}
/**
* Determines whether the specified Class object represents an actual class, and not an Annotation, Array, Enum,
* Interface or Primitive type.
*
* @param type the Class object tested as an actual class.
* @return true iff the Class object is not null and represents an actual class.
*/
@NullSafe
public static boolean isClass(Class type) {
return (type != null && !(type.isAnnotation() || type.isArray() || type.isEnum() || type.isInterface()
|| type.isPrimitive()));
}
/**
* Null-safe method to determine whether the given {@link Constructor} accepts a single argument
* of type {@link Object[]} used to pass arguments much like a Java {@link Class} {@literal main} method.
*
* This determination makes no effort to distinguish {@link Constructor Constructors} that accept an arbitrary
* {@link Object[]} that do not represent arguments. Therefore, this method should only be used when the developer
* knows such a constructor exists for his/her particular UC.
*
* @param constructor {@link Constructor} to evaluate.
* @return a boolean value indicating whether the given {@link Constructor} accepts a {@link Object[]} of arguments.
* @see java.lang.reflect.Constructor
*/
@NullSafe
public static boolean isConstructorWithArrayParameter(Constructor> constructor) {
return (constructor != null && constructor.getParameterCount() == 1
&& Object[].class.isAssignableFrom(constructor.getParameterTypes()[0]));
}
/**
* Determines whether the given {@link Constructor} is a default constructor.
*
* A {@link Constructor} is the default constructor if it is public and has no parameters.
*
* @param constructor {@link Constructor} to evaluate.
* @return a boolean value indicating whether the given {@link Constructor} is the default constructor.
* @see java.lang.reflect.Constructor
*/
@NullSafe
public static boolean isDefaultConstructor(Constructor> constructor) {
return (ModifierUtils.isPublic(constructor) && constructor.getParameterCount() == 0);
}
/**
* Determines whether the specified Class object represents an enum type.
*
* @param type the Class object tested as an enum type.
* @return true iff the Class object is not null and represents an enum type.
* @see java.lang.Class#isEnum()
*/
@NullSafe
public static boolean isEnum(Class type) {
return (type != null && type.isEnum());
}
/**
* Determines whether the specified Class object represents an interface.
*
* @param type the Class object tested as an interface.
* @return true iff the Class object is not null and represents an interface.
* @see java.lang.Class#isInterface()
*/
@NullSafe
public static boolean isInterface(Class type) {
return (type != null && type.isInterface());
}
/**
* Determines whether the given Java {@link Class} {@link Method} is the {@literal main} {@link Method}.
*
* @param method {@link Method} to evaluate.
* @return a boolean value indicating whether the given {@link Method}
* is a Java {@link Class} {@literal main} {@link Method}.
* @see java.lang.reflect.Method
*/
@NullSafe
public static boolean isMainMethod(Method method) {
return Optional.ofNullable(method).map(localMethod -> MAIN_METHOD_NAME.equals(localMethod.getName())
&& ModifierUtils.isPublic(localMethod)
&& ModifierUtils.isStatic(localMethod)
&& void.class.equals(localMethod.getReturnType())
&& localMethod.getParameterCount() == 1
&& localMethod.getParameterTypes()[0].equals(String[].class))
.orElse(false);
}
/**
* Determines whether the specified class identified by name is available and present on the application classpath.
*
* @param className the fully qualified name of the class to determine the presence of.
* @return a boolean value indicating whether the class identified by name is in the classpath.
* @see #loadClass(String)
*/
public static boolean isPresent(String className) {
try {
return (loadClass(className) != null);
}
catch (TypeNotFoundException ignore) {
return false;
}
}
/**
* Determines whether the specified Class object represents a primitive type.
*
* @param type the Class object tested as a primitive type.
* @return true iff the Class object is not null and represents a primitive type.
* @see java.lang.Class#isPrimitive()
*/
@NullSafe
public static boolean isPrimitive(Class type) {
return (type != null && type.isPrimitive());
}
/**
* Loads the Class object for the specified, fully qualified class name using the current Thread's context ClassLoader,
* following by initializing the class.
*
* @param {@link Class} type of T.
* @param fullyQualifiedClassName a String value indicating the fully qualified class name of the Class to load.
* @return a Class object for the specified, fully-qualified class name.
* @throws TypeNotFoundException if the Class identified by the fully qualified class name could not be found.
* @see #loadClass(String, boolean, ClassLoader)
* @see java.lang.Thread#currentThread()
* @see java.lang.Thread#getContextClassLoader()
*/
public static Class loadClass(String fullyQualifiedClassName) {
return loadClass(fullyQualifiedClassName, DEFAULT_INITIALIZE_LOADED_CLASS,
Thread.currentThread().getContextClassLoader());
}
/**
* Loads the Class object for the specified, fully qualified class name using the provided ClassLoader and the option
* to initialize the class (calling any static initializers) once loaded.
*
* @param {@link Class} type of T.
* @param fullyQualifiedClassName a String indicating the fully qualified class name of the Class to load.
* @param initialize a boolean value indicating whether to initialize the class after loading.
* @param classLoader the ClassLoader used to load the class.
* @return a Class object for the specified, fully-qualified class name.
* @throws TypeNotFoundException if the Class identified by the fully qualified class name could not be found.
* @see java.lang.Class#forName(String, boolean, ClassLoader)
*/
@SuppressWarnings("unchecked")
public static Class loadClass(String fullyQualifiedClassName, boolean initialize, ClassLoader classLoader) {
try {
return (Class) Class.forName(fullyQualifiedClassName, initialize, classLoader);
}
catch (ClassNotFoundException | NoClassDefFoundError e) {
throw new TypeNotFoundException(String.format("Class [%s] was not found", fullyQualifiedClassName), e);
}
}
/**
* Locates the class file resource given the binary name of the {@link Class}.
*
* @param binaryName a String with the binary name of the {@link Class} that's class file resource will be located.
* @return a {@link URL} with the location of the class file resource containing the {@link Class} definition
* for the given binary name.
* @see #locateClass(String, ClassLoader)
* @see java.net.URL
*/
public static URL locateClass(String binaryName) {
return locateClass(binaryName, Thread.currentThread().getContextClassLoader());
}
/**
* Locates the class file resource given the binary name of the {@link Class}. The {@link ClassLoader} used
* to search class file resource for the {@link Class} with the given binary name.
*
* @param binaryName a String with the binary name of the {@link Class} that's class file resource will be located.
* @param classLoader the {@link ClassLoader} used to locate the class file resource for the {@link Class}
* with the given binary name.
* @return a {@link URL} with the location of the class file resource containing the {@link Class} definition
* for the given binary name.
* @see java.net.URL
*/
public static URL locateClass(String binaryName, ClassLoader classLoader) {
try {
Class> type = loadClass(binaryName, false, classLoader);
return type.getClassLoader().getResource(getResourceName(type));
}
catch (TypeNotFoundException ignore) {
return null;
}
}
/**
* Determines whether the Object is an instance of any of the Class types and returns false if it is.
*
* @param obj the Object of the instanceof comparison.
* @param types an array of Class types used in the instanceof comparison.
* @return a true boolean value iff the Object is not an instance of any of the Class types.
* @see #instanceOf(Object, Class)
*/
@NullSafe
@SuppressWarnings("all")
public static boolean notInstanceOf(Object obj, Class... types) {
boolean result = true;
for (int index = 0; result && index < ArrayUtils.nullSafeLength(types); index++) {
result &= !instanceOf(obj, types[index]);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy