Class ClassUtilities
Class
objects and related operations.
ClassUtilities
includes functionalities such as:
- Determining inheritance distance between two classes or interfaces (
computeInheritanceDistance(java.lang.Class<?>, java.lang.Class<?>)
). - Checking if a class is primitive or a primitive wrapper (
isPrimitive(java.lang.Class<?>)
). - Converting between primitive types and their wrapper classes (
toPrimitiveWrapperClass(java.lang.Class<?>)
). - Loading resources from the classpath as strings or byte arrays (
loadResourceAsString(java.lang.String)
andloadResourceAsBytes(java.lang.String)
). - Providing custom mappings for class aliases (
addPermanentClassAlias(java.lang.Class<?>, java.lang.String)
andremovePermanentClassAlias(java.lang.String)
). - Identifying whether all constructors in a class are private (
areAllConstructorsPrivate(java.lang.Class<?>)
). - Finding the most specific matching class in an inheritance hierarchy (
findClosest(java.lang.Class<?>, java.util.Map<java.lang.Class<?>, T>, T)
).
Inheritance Distance
The computeInheritanceDistance(Class, Class)
method calculates the number of inheritance steps
between two classes or interfaces. If there is no relationship, it returns -1
.
Primitive and Wrapper Handling
- Supports identification of primitive types and their wrappers.
- Handles conversions between primitive types and their wrapper classes.
- Considers primitive types and their wrappers interchangeable for certain operations.
Resource Loading
Includes methods for loading resources from the classpath as strings or byte arrays, throwing appropriate exceptions if the resource cannot be found or read.
OSGi and JPMS ClassLoader Support
Detects and supports environments such as OSGi or JPMS for proper class loading. Uses caching for efficient retrieval of class loaders in these environments.
Design Notes
- This class is designed to be a static utility class and should not be instantiated.
- It uses internal caching for operations like class aliasing and OSGi class loading to optimize performance.
Usage Example
// Compute inheritance distance
int distance = ClassUtilities.computeInheritanceDistance(ArrayList.class, List.class); // Outputs 1
// Check if a class is primitive
boolean isPrimitive = ClassUtilities.isPrimitive(int.class); // Outputs true
// Load a resource as a string
String resourceContent = ClassUtilities.loadResourceAsString("example.txt");
- Author:
- John DeRegnaucourt ([email protected])
Copyright (c) Cedar Software LLC
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
License
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. - See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic void
addPermanentClassAlias
(Class<?> clazz, String alias) Registers a permanent alias name for a class to support Class.forName() lookups.static boolean
Determines if all constructors in a class are declared as private.static int
computeInheritanceDistance
(Class<?> source, Class<?> destination) Computes the inheritance distance between two classes/interfaces/primitive types.static boolean
doesOneWrapTheOther
(Class<?> x, Class<?> y) Determines if one class is the wrapper type of the other.static <T> T
findClosest
(Class<?> clazz, Map<Class<?>, T> candidateClasses, T defaultClass) Finds the closest matching class in an inheritance hierarchy from a map of candidate classes.static Class
<?> forName
(String name, ClassLoader classLoader) Given the passed in String class name, return the named JVM class.static Class
<?> getClassIfEnum
(Class<?> c) Determines if a class is an enum or is related to an enum through inheritance or enclosure.static ClassLoader
Obtains the appropriate ClassLoader depending on whether the environment is OSGi, JPMS, or neither.static ClassLoader
getClassLoader
(Class<?> anchorClass) Obtains the appropriate ClassLoader depending on whether the environment is OSGi, JPMS, or neither.static int
indexOfSmallestValue
(int[] array) Returns the index of the smallest value in an array.static boolean
isClassFinal
(Class<?> c) Determines if a class is declared as final.static boolean
isPrimitive
(Class<?> c) static byte[]
loadResourceAsBytes
(String resourceName) Loads resource content as a byte[].static String
loadResourceAsString
(String resourceName) Loads resource content as a String.static Object
newInstance
(Converter converter, Class<?> c, Collection<?> argumentValues) Create a new instance of the specified class, optionally using provided constructor arguments.static void
removePermanentClassAlias
(String alias) Removes a previously registered class alias.static void
setUseUnsafe
(boolean state) Globally turn on (or off) the 'unsafe' option of Class construction.static Class
<?> toPrimitiveWrapperClass
(Class<?> primitiveClass) Converts a primitive class to its corresponding wrapper class.
-
Constructor Details
-
ClassUtilities
public ClassUtilities()
-
-
Method Details
-
addPermanentClassAlias
Registers a permanent alias name for a class to support Class.forName() lookups.- Parameters:
clazz
- the class to aliasalias
- the alternative name for the class
-
removePermanentClassAlias
Removes a previously registered class alias.- Parameters:
alias
- the alias name to remove
-
computeInheritanceDistance
Computes the inheritance distance between two classes/interfaces/primitive types.- Parameters:
source
- The source class, interface, or primitive type.destination
- The destination class, interface, or primitive type.- Returns:
- The number of steps from the source to the destination, or -1 if no path exists.
-
isPrimitive
- Parameters:
c
- Class to test- Returns:
- boolean true if the passed in class is a Java primitive, false otherwise. The Wrapper classes Integer, Long, Boolean, etc. are considered primitives by this method.
-
forName
Given the passed in String class name, return the named JVM class.- Parameters:
name
- String name of a JVM class.classLoader
- ClassLoader to use when searching for JVM classes.- Returns:
- Class instance of the named JVM class or null if not found.
-
isClassFinal
Determines if a class is declared as final.Checks if the class has the
final
modifier, indicating that it cannot be subclassed.Example:
boolean isFinal = ClassUtilities.isClassFinal(String.class); // Returns true boolean notFinal = ClassUtilities.isClassFinal(ArrayList.class); // Returns false
- Parameters:
c
- the class to check, must not be null- Returns:
- true if the class is final, false otherwise
- Throws:
NullPointerException
- if the input class is null
-
areAllConstructorsPrivate
Determines if all constructors in a class are declared as private.This method is useful for identifying classes that enforce singleton patterns or utility classes that should not be instantiated.
Example:
// Utility class with private constructor public final class Utils { private Utils() {} } boolean isPrivate = ClassUtilities.areAllConstructorsPrivate(Utils.class); // Returns true boolean notPrivate = ClassUtilities.areAllConstructorsPrivate(String.class); // Returns false
- Parameters:
c
- the class to check, must not be null- Returns:
- true if all constructors in the class are private, false if any constructor is non-private
- Throws:
NullPointerException
- if the input class is null
-
toPrimitiveWrapperClass
Converts a primitive class to its corresponding wrapper class.If the input class is already a non-primitive type, it is returned unchanged. For primitive types, returns the corresponding wrapper class (e.g.,
int.class
→Integer.class
).Examples:
Class<?> intWrapper = ClassUtilities.toPrimitiveWrapperClass(int.class); // Returns Integer.class Class<?> boolWrapper = ClassUtilities.toPrimitiveWrapperClass(boolean.class); // Returns Boolean.class Class<?> sameClass = ClassUtilities.toPrimitiveWrapperClass(String.class); // Returns String.class
Supported Primitive Types:
boolean.class
→Boolean.class
byte.class
→Byte.class
char.class
→Character.class
double.class
→Double.class
float.class
→Float.class
int.class
→Integer.class
long.class
→Long.class
short.class
→Short.class
void.class
→Void.class
- Parameters:
primitiveClass
- the class to convert, must not be null- Returns:
- the wrapper class if the input is primitive, otherwise the input class itself
- Throws:
NullPointerException
- if the input class is nullIllegalArgumentException
- if the input class is not a recognized primitive type
-
doesOneWrapTheOther
Determines if one class is the wrapper type of the other.This method checks if there is a primitive-wrapper relationship between two classes. For example,
Integer.class
wrapsint.class
and vice versa.Examples:
boolean wraps = ClassUtilities.doesOneWrapTheOther(Integer.class, int.class); // Returns true boolean wraps2 = ClassUtilities.doesOneWrapTheOther(int.class, Integer.class); // Returns true boolean noWrap = ClassUtilities.doesOneWrapTheOther(Integer.class, long.class); // Returns false
Supported Wrapper Pairs:
Boolean.class
↔boolean.class
Byte.class
↔byte.class
Character.class
↔char.class
Double.class
↔double.class
Float.class
↔float.class
Integer.class
↔int.class
Long.class
↔long.class
Short.class
↔short.class
- Parameters:
x
- first class to checky
- second class to check- Returns:
- true if one class is the wrapper of the other, false otherwise
- Throws:
NullPointerException
- if either input class is null
-
getClassLoader
Obtains the appropriate ClassLoader depending on whether the environment is OSGi, JPMS, or neither.- Returns:
- the appropriate ClassLoader
-
getClassLoader
Obtains the appropriate ClassLoader depending on whether the environment is OSGi, JPMS, or neither.- Parameters:
anchorClass
- the class to use as reference for loading- Returns:
- the appropriate ClassLoader
-
findClosest
Finds the closest matching class in an inheritance hierarchy from a map of candidate classes.This method searches through a map of candidate classes to find the one that is most closely related to the input class in terms of inheritance distance. The search prioritizes:
- Exact class match (returns immediately)
- Closest superclass/interface in the inheritance hierarchy
This method is typically used for cache misses when looking up class-specific handlers or processors.
- Type Parameters:
T
- The type of value stored in the candidateClasses map- Parameters:
clazz
- The class to find a match for (must not be null)candidateClasses
- Map of candidate classes and their associated values (must not be null)defaultClass
- Default value to return if no suitable match is found- Returns:
- The value associated with the closest matching class, or defaultClass if no match found
- Throws:
NullPointerException
- if clazz or candidateClasses is null- See Also:
-
loadResourceAsString
Loads resource content as a String.- Parameters:
resourceName
- Name of the resource file.- Returns:
- Content of the resource file as a String.
-
loadResourceAsBytes
Loads resource content as a byte[].- Parameters:
resourceName
- Name of the resource file.- Returns:
- Content of the resource file as a byte[].
- Throws:
IllegalArgumentException
- if the resource cannot be foundUncheckedIOException
- if there is an error reading the resourceNullPointerException
- if resourceName is null
-
indexOfSmallestValue
public static int indexOfSmallestValue(int[] array) Returns the index of the smallest value in an array.- Parameters:
array
- The array to search.- Returns:
- The index of the smallest value, or -1 if the array is empty.
-
getClassIfEnum
Determines if a class is an enum or is related to an enum through inheritance or enclosure.This method searches for an enum class in two ways:
- Checks if the input class or any of its superclasses is an enum
- If no enum is found in the inheritance hierarchy, checks if any enclosing (outer) classes are enums
- Parameters:
c
- The class to check (may be null)- Returns:
- The related enum class if found, null otherwise
- See Also:
-
newInstance
Create a new instance of the specified class, optionally using provided constructor arguments.This method attempts to instantiate a class using the following strategies in order:
- Using cached constructor information from previous successful instantiations
- Matching constructor parameters with provided argument values
- Using default values for unmatched parameters
- Using unsafe instantiation (if enabled)
Constructor selection prioritizes:
- Public over non-public constructors
- Protected over private constructors
- Constructors with more non-null argument matches
- Constructors with more parameters
- Parameters:
converter
- Converter instance used to convert null values to appropriate defaults for primitive typesc
- Class to instantiateargumentValues
- Optional collection of values to match to constructor parameters. Can be null or empty.- Returns:
- A new instance of the specified class
- Throws:
IllegalArgumentException
- if:- The class cannot be instantiated
- The class is a security-sensitive class (Process, ClassLoader, etc.)
- The class is an unknown interface
IllegalStateException
- if constructor invocation failsSecurity Note: For security reasons, this method prevents instantiation of:
- ProcessBuilder
- Process
- ClassLoader
- Constructor
- Method
- Field
Usage Example:
// Create instance with no arguments MyClass obj1 = (MyClass) newInstance(converter, MyClass.class, null); // Create instance with constructor arguments List<Object> args = Arrays.asList("arg1", 42); MyClass obj2 = (MyClass) newInstance(converter, MyClass.class, args);
-
setUseUnsafe
public static void setUseUnsafe(boolean state) Globally turn on (or off) the 'unsafe' option of Class construction. The unsafe option is used when all constructors have been tried and the Java class could not be instantiated.- Parameters:
state
- boolean true = on, false = off.
-