Class Converter
Supports conversion from primitive types to their corresponding wrapper classes, Number classes,
Date and Time classes (e.g., Date
, Timestamp
, LocalDate
, LocalDateTime
,
ZonedDateTime
, Calendar
), BigInteger
, BigDecimal
, Atomic classes
(e.g., AtomicBoolean
, AtomicInteger
, AtomicLong
), Class
, UUID
,
String
, Collection classes (e.g., List
, Set
, Map
), ByteBuffer, CharBuffer,
and other related classes.
The Converter includes thousands of built-in conversions. Use the getSupportedConversions()
API to view all source-to-target conversion mappings.
The primary API is convert(Object, Class)
. For example:
Long x = convert("35", Long.class);
Date d = convert("2015/01/01", Date.class);
int y = convert(45.0, int.class);
String dateStr = convert(date, String.class);
String dateStr = convert(calendar, String.class);
Short t = convert(true, short.class); // returns (short) 1 or 0
Long time = convert(calendar, long.class); // retrieves calendar's time as long
Map<String, Object> map = Map.of("_v", "75.0");
Double value = convert(map, double.class); // Extracts "_v" key and converts it
Null Handling: If a null value is passed as the source, the Converter returns:
- null for object types
- 0 for numeric primitive types
- false for boolean primitives
- ' ' for char primitives
Map Conversions: A Map
can be converted to almost all supported JDK data classes.
For example, UUID
can be converted to/from a Map
with keys like "mostSigBits" and "leastSigBits".
Date/Time classes expect specific keys such as "time" or "nanos". For other classes, the Converter typically
looks for a "value" key to source the conversion.
Extensibility: Additional conversions can be added by specifying the source class, target class,
and a conversion function (e.g., a lambda). Use the addConversion(Class, Class, Convert)
method to register
custom converters. This allows for the inclusion of new Collection types and other custom types as needed.
Supported Collection Conversions: The Converter supports conversions involving various Collection types, including but not limited to:
List
Set
Map
Collection
- Arrays (e.g.,
byte[]
,char[]
,ByteBuffer
,CharBuffer
)
Usage Example:
ConverterOptions options = new ConverterOptions();
Converter converter = new Converter(options);
// Convert String to Integer
Integer number = converter.convert("123", Integer.class);
// Convert Enum to String
Day day = Day.MONDAY;
String dayStr = converter.convert(day, String.class);
// Convert Object[], String[], Collection, and primitive Arrays to EnumSet
Object[] array = {Day.MONDAY, Day.WEDNESDAY, "FRIDAY", 4};
EnumSet<Day> daySet = (EnumSet<Day>)(Object)converter.convert(array, Day.class);
Enum, String, and Number value in the source collection/array is properly converted
to the correct Enum type and added to the returned EnumSet. Null values inside the
source (Object[], Collection) are skipped.
When converting arrays or collections to EnumSet, you must use a double cast due to Java's
type system and generic type erasure. The cast is safe as the converter guarantees return of
an EnumSet when converting arrays/collections to enum types.
// Add a custom conversion from String to CustomType
converter.addConversion(String.class, CustomType.class, (from, conv) -> new CustomType(from));
// Convert using the custom converter
CustomType custom = converter.convert("customValue", CustomType.class);
- 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.
-
Method Summary
Modifier and TypeMethodDescriptionstatic Convert<?>
addConversion
(Class<?> source, Class<?> target, Convert<?> conversionFunction) Adds a new conversion function for converting from one type to another.Retrieves a map of all supported conversions, categorized by source and target classes.static <T> T
Converts the given source object to the specified target type.static AtomicBoolean
convert2AtomicBoolean
(Object fromInstance) Convert from the passed in instance to an AtomicBoolean.static AtomicInteger
convert2AtomicInteger
(Object fromInstance) Convert from the passed in instance to an AtomicInteger.static AtomicLong
convert2AtomicLong
(Object fromInstance) Convert from the passed in instance to an AtomicLong.static BigDecimal
convert2BigDecimal
(Object fromInstance) Convert from the passed in instance to a BigDecimal.static BigInteger
convert2BigInteger
(Object fromInstance) Convert from the passed in instance to a BigInteger.static boolean
convert2boolean
(Object fromInstance) Convert from the passed in instance to a boolean.static byte
convert2byte
(Object fromInstance) Convert from the passed in instance to a byte.static char
convert2char
(Object fromInstance) Convert from the passed in instance to a char.static double
convert2double
(Object fromInstance) Convert from the passed in instance to a double.static float
convert2float
(Object fromInstance) Convert from the passed in instance to a float.static int
convert2int
(Object fromInstance) Convert from the passed in instance to an int.static long
convert2long
(Object fromInstance) Convert from the passed in instance to an long.static short
convert2short
(Object fromInstance) Convert from the passed in instance to a short.static String
convert2String
(Object fromInstance) Convert from the passed in instance to a String.static AtomicBoolean
convertToAtomicBoolean
(Object fromInstance) Convert from the passed in instance to an AtomicBoolean.static AtomicInteger
convertToAtomicInteger
(Object fromInstance) Convert from the passed in instance to an AtomicInteger.static AtomicLong
convertToAtomicLong
(Object fromInstance) Convert from the passed in instance to an AtomicLong.static BigDecimal
convertToBigDecimal
(Object fromInstance) Convert from the passed in instance to a BigDecimal.static BigInteger
convertToBigInteger
(Object fromInstance) Convert from the passed in instance to a BigInteger.static Boolean
convertToBoolean
(Object fromInstance) Convert from the passed in instance to a Boolean.static Byte
convertToByte
(Object fromInstance) Convert from the passed in instance to a Byte.static Calendar
convertToCalendar
(Object fromInstance) Convert from the passed in instance to a Calendar.static Character
convertToCharacter
(Object fromInstance) Convert from the passed in instance to a Character.static Date
convertToDate
(Object fromInstance) Convert from the passed in instance to a Date.static Double
convertToDouble
(Object fromInstance) Convert from the passed in instance to a Double.static Float
convertToFloat
(Object fromInstance) Convert from the passed in instance to a Float.static Integer
convertToInteger
(Object fromInstance) Convert from the passed in instance to an Integer.static LocalDate
convertToLocalDate
(Object fromInstance) Convert from the passed in instance to a LocalDate.static LocalDateTime
convertToLocalDateTime
(Object fromInstance) Convert from the passed in instance to a LocalDateTime.static Long
convertToLong
(Object fromInstance) Convert from the passed in instance to a Long.static Short
convertToShort
(Object fromInstance) Convert from the passed in instance to a Short.static Date
convertToSqlDate
(Object fromInstance) Convert from the passed in instance to a java.sql.Date.static String
convertToString
(Object fromInstance) Convert from the passed in instance to a String.static Timestamp
convertToTimestamp
(Object fromInstance) Convert from the passed in instance to a Timestamp.static ZonedDateTime
convertToZonedDateTime
(Object fromInstance) Convert from the passed in instance to a Date.Retrieves a map of all supported conversions with class names instead of class objects.static boolean
isConversionSupportedFor
(Class<?> source, Class<?> target) Determines whether a conversion from the specified source type to the target type is supported.static boolean
isDirectConversionSupported
(Class<?> source, Class<?> target) Determines whether a direct conversion from the specified source type to the target type is supported, without considering inheritance hierarchies.static boolean
isSimpleTypeConversionSupported
(Class<?> source, Class<?> target) Determines whether a conversion from the specified source type to the target type is supported, excluding any conversions involving arrays or collections.static long
localDateTimeToMillis
(LocalDateTime localDateTime) Deprecated.static long
localDateToMillis
(LocalDate localDate) Deprecated.static long
zonedDateTimeToMillis
(ZonedDateTime zonedDateTime) Deprecated.
-
Method Details
-
convert
Converts the given source object to the specified target type.The
convert
method serves as the primary API for transforming objects between various types. It supports a wide range of conversions, including primitive types, wrapper classes, numeric types, date and time classes, collections, and custom objects. Additionally, it allows for extensibility by enabling the registration of custom converters.Key Features:
- Wide Range of Supported Types: Supports conversion between Java primitives, their corresponding
wrapper classes,
Number
subclasses, date and time classes (e.g.,Date
,LocalDateTime
), collections (e.g.,List
,Set
,Map
),UUID
, and more. - Null Handling: Gracefully handles
null
inputs by returningnull
for object types, default primitive values (e.g., 0 for numeric types,false
for boolean), and default characters. - Inheritance-Based Conversions: Automatically considers superclass and interface hierarchies to find the most suitable converter when a direct conversion is not available.
- Custom Converters: Allows users to register custom conversion logic for specific source-target type pairs
using the
addConversion(Class, Class, Convert)
method. - Thread-Safe: Designed to be thread-safe, allowing concurrent conversions without compromising data integrity.
Usage Examples:
ConverterOptions options = new ConverterOptions(); Converter converter = new Converter(options); // Example 1: Convert String to Integer String numberStr = "123"; Integer number = converter.convert(numberStr, Integer.class); System.out.println("Converted Integer: " + number); // Output: Converted Integer: 123 // Example 2: Convert String to Date String dateStr = "2024-04-27"; LocalDate date = converter.convert(dateStr, LocalDate.class); System.out.println("Converted Date: " + date); // Output: Converted Date: 2024-04-27 // Example 3: Convert Enum to String Day day = Day.MONDAY; String dayStr = converter.convert(day, String.class); System.out.println("Converted Day: " + dayStr); // Output: Converted Day: MONDAY // Example 4: Convert Array to List String[] stringArray = {"apple", "banana", "cherry"}; List<String> stringList = converter.convert(stringArray, List.class); System.out.println("Converted List: " + stringList); // Output: Converted List: [apple, banana, cherry] // Example 5: Convert Map to UUID Map<String, Object> uuidMap = Map.of("mostSigBits", 123456789L, "leastSigBits", 987654321L); UUID uuid = converter.convert(uuidMap, UUID.class); System.out.println("Converted UUID: " + uuid); // Output: Converted UUID: 00000000-075b-cd15-0000-0000003ade68 // Example 6: Convert Object[], String[], Collection, and primitive Arrays to EnumSet Object[] array = {Day.MONDAY, Day.WEDNESDAY, "FRIDAY", 4}; EnumSet<Day> daySet = (EnumSet<Day>)(Object)converter.convert(array, Day.class); Enum, String, and Number value in the source collection/array is properly converted to the correct Enum type and added to the returned EnumSet. Null values inside the source (Object[], Collection) are skipped. When converting arrays or collections to EnumSet, you must use a double cast due to Java's type system and generic type erasure. The cast is safe as the converter guarantees return of an EnumSet when converting arrays/collections to enum types. // Example 7: Register and Use a Custom Converter // Custom converter to convert String to CustomType converter.addConversion(String.class, CustomType.class, (from, conv) -> new CustomType(from)); String customStr = "customValue"; CustomType custom = converter.convert(customStr, CustomType.class); System.out.println("Converted CustomType: " + custom); // Output: Converted CustomType: CustomType{value='customValue'}
Parameter Descriptions:
- from: The source object to be converted. This can be any object, including
null
. The actual type offrom
does not need to match the target type; the Converter will attempt to perform the necessary transformation. - toType: The target class to which the source object should be converted. This parameter
specifies the desired output type. It can be a primitive type (e.g.,
int.class
), a wrapper class (e.g.,Integer
.class), or any other supported class.
Return Value:
Returns an instance of the specified target type
toType
, representing the converted value of the source objectfrom
. Iffrom
isnull
, the method returns:null
for non-primitive target types.- Default primitive values for primitive target types (e.g., 0 for numeric types,
false
forboolean
, ' ' forchar
).
Exceptions:
- IllegalArgumentException: Thrown if the conversion from the source type to the target type is not supported,
or if the target type
toType
isnull
. - RuntimeException: Any underlying exception thrown during the conversion process is propagated as a
RuntimeException
.
Supported Conversions:
The Converter supports a vast array of conversions, including but not limited to:
- Primitives and Wrappers: Convert between Java primitive types (e.g.,
int
,boolean
) and their corresponding wrapper classes (e.g.,Integer
,Boolean
). - Numbers: Convert between different numeric types (e.g.,
Integer
toDouble
,BigInteger
toBigDecimal
). - Date and Time: Convert between various date and time classes (e.g.,
String
toLocalDate
,Date
toInstant
,Calendar
toZonedDateTime
). - Collections: Convert between different collection types (e.g., arrays to
List
,Set
toMap
,StringBuilder
toString
). - Custom Objects: Convert between complex objects (e.g.,
UUID
toMap
,Class
toString
, custom types via user-defined converters). - Buffer Types: Convert between buffer types (e.g.,
ByteBuffer
toString
,CharBuffer
toByte
[]).
Extensibility:
Users can extend the Converter's capabilities by registering custom converters for specific type pairs. This is accomplished using the
addConversion(Class, Class, Convert)
method, which accepts the source type, target type, and aConvert
functional interface implementation that defines the conversion logic.Performance Considerations:
The Converter utilizes caching mechanisms to store and retrieve converters, ensuring efficient performance even with a large number of conversion operations. However, registering an excessive number of custom converters may impact memory usage. It is recommended to register only necessary converters to maintain optimal performance.
- Type Parameters:
T
- The type of the target object.- Parameters:
from
- The source object to be converted. Can be any object, includingnull
.toType
- The target class to which the source object should be converted. Must not benull
.- Returns:
- An instance of
toType
representing the converted value offrom
. - Throws:
IllegalArgumentException
- iftoType
isnull
or if the conversion is not supported.- See Also:
- Wide Range of Supported Types: Supports conversion between Java primitives, their corresponding
wrapper classes,
-
isConversionSupportedFor
Determines whether a conversion from the specified source type to the target type is supported. For array-to-array conversions, this method verifies that both array conversion and component type conversions are supported.The method checks three paths for conversion support:
- Direct conversions as defined in the conversion maps
- Collection/Array/EnumSet conversions - for array-to-array conversions, also verifies that component type conversions are supported
- Inherited conversions (via superclasses and implemented interfaces)
For array conversions, this method performs a deep check to ensure both the array types and their component types can be converted. For example, when checking if a String[] can be converted to Integer[], it verifies both:
- That array-to-array conversion is supported
- That String-to-Integer conversion is supported for the components
- Parameters:
source
- The source class typetarget
- The target class type- Returns:
- true if the conversion is fully supported (including component type conversions for arrays), false otherwise
-
isDirectConversionSupported
Determines whether a direct conversion from the specified source type to the target type is supported, without considering inheritance hierarchies. For array-to-array conversions, verifies that both array conversion and component type conversions are directly supported.The method checks:
- User-defined and built-in direct conversions
- Collection/Array/EnumSet conversions - for array-to-array conversions, also verifies that component type conversions are directly supported
For array conversions, performs a deep check to ensure both the array types and their component types can be converted directly. For example, when checking if a String[] can be converted to Integer[], verifies both:
- That array-to-array conversion is supported
- That String-to-Integer conversion is directly supported
- Parameters:
source
- The source class typetarget
- The target class type- Returns:
true
if a direct conversion exists (including component type conversions for arrays),false
otherwise
-
isSimpleTypeConversionSupported
Determines whether a conversion from the specified source type to the target type is supported, excluding any conversions involving arrays or collections.The method is particularly useful when you need to verify that a conversion is possible between simple types without considering array or collection conversions. This can be helpful in scenarios where you need to validate component type conversions separately from their container types.
Example usage:
// Check if String can be converted to Integer boolean canConvert = Converter.isSimpleTypeConversionSupported( String.class, Integer.class); // returns true // Check array conversion (always returns false) boolean arrayConvert = Converter.isSimpleTypeConversionSupported( String[].class, Integer[].class); // returns false // Intentionally repeat source type (class) - will find identity conversion // Let's us know that it is a "simple" type (String, Date, Class, UUID, URL, Temporal type, etc.) boolean isSimpleType = Converter.isSimpleTypeConversionSupported( ZonedDateTime.class, ZonedDateTime.class); // Check collection conversion (always returns false) boolean listConvert = Converter.isSimpleTypeConversionSupported( List.class, Set.class); // returns false
- Parameters:
source
- The source class type to checktarget
- The target class type to check- Returns:
true
if a non-collection conversion exists between the types,false
if either type is an array/collection or no conversion exists- See Also:
-
allSupportedConversions
Retrieves a map of all supported conversions, categorized by source and target classes.The returned map's keys are source classes, and each key maps to a
Set
of target classes that the source can be converted to.- Returns:
- A
Map<Class<?>, Set<Class<?>>>
representing all supported conversions.
-
getSupportedConversions
Retrieves a map of all supported conversions with class names instead of class objects.The returned map's keys are source class names, and each key maps to a
Set
of target class names that the source can be converted to.- Returns:
- A
Map<String, Set<String>>
representing all supported conversions by class names.
-
addConversion
public static Convert<?> addConversion(Class<?> source, Class<?> target, Convert<?> conversionFunction) Adds a new conversion function for converting from one type to another. If a conversion already exists for the specified source and target types, the existing conversion will be overwritten.When
convert(source, target)
is called, the conversion function is located by matching the class of the source instance and the target class. If an exact match is found, that conversion function is used. If no exact match is found, the method attempts to find the most appropriate conversion by traversing the class hierarchy of the source and target types (including interfaces), excluding common marker interfaces such asSerializable
,Comparable
, andCloneable
. The nearest match based on class inheritance and interface implementation is used.This method allows you to explicitly define custom conversions between types. It also supports the automatic handling of primitive types by converting them to their corresponding wrapper types (e.g.,
int
toInteger
).Note: This method utilizes the
ClassUtilities.toPrimitiveWrapperClass(Class)
utility to ensure that primitive types are mapped to their respective wrapper classes before attempting to locate or store the conversion.- Parameters:
source
- The source class (type) to convert from.target
- The target class (type) to convert to.conversionFunction
- A function that converts an instance of the source type to an instance of the target type.- Returns:
- The previous conversion function associated with the source and target types, or
null
if no conversion existed.
-
convert2String
Convert from the passed in instance to a String. If null is passed in, this method will return "". Call 'getSupportedConversions()' to see all conversion options for all Classes (all sources to all destinations). -
convertToString
Convert from the passed in instance to a String. If null is passed in, this method will return null. -
convert2BigDecimal
Convert from the passed in instance to a BigDecimal. If null or "" is passed in, this method will return a BigDecimal with the value of 0. -
convertToBigDecimal
Convert from the passed in instance to a BigDecimal. If null is passed in, this method will return null. If "" is passed in, this method will return a BigDecimal with the value of 0. -
convert2BigInteger
Convert from the passed in instance to a BigInteger. If null or "" is passed in, this method will return a BigInteger with the value of 0. -
convertToBigInteger
Convert from the passed in instance to a BigInteger. If null is passed in, this method will return null. If "" is passed in, this method will return a BigInteger with the value of 0. -
convertToSqlDate
Convert from the passed in instance to a java.sql.Date. If null is passed in, this method will return null. -
convertToTimestamp
Convert from the passed in instance to a Timestamp. If null is passed in, this method will return null. -
convertToDate
Convert from the passed in instance to a Date. If null is passed in, this method will return null. -
convertToLocalDate
Convert from the passed in instance to a LocalDate. If null is passed in, this method will return null. -
convertToLocalDateTime
Convert from the passed in instance to a LocalDateTime. If null is passed in, this method will return null. -
convertToZonedDateTime
Convert from the passed in instance to a Date. If null is passed in, this method will return null. -
convertToCalendar
Convert from the passed in instance to a Calendar. If null is passed in, this method will return null. -
convert2char
Convert from the passed in instance to a char. If null is passed in, (char) 0 is returned. -
convertToCharacter
Convert from the passed in instance to a Character. If null is passed in, null is returned. -
convert2byte
Convert from the passed in instance to a byte. If null is passed in, (byte) 0 is returned. -
convertToByte
Convert from the passed in instance to a Byte. If null is passed in, null is returned. -
convert2short
Convert from the passed in instance to a short. If null is passed in, (short) 0 is returned. -
convertToShort
Convert from the passed in instance to a Short. If null is passed in, null is returned. -
convert2int
Convert from the passed in instance to an int. If null is passed in, (int) 0 is returned. -
convertToInteger
Convert from the passed in instance to an Integer. If null is passed in, null is returned. -
convert2long
Convert from the passed in instance to an long. If null is passed in, (long) 0 is returned. -
convertToLong
Convert from the passed in instance to a Long. If null is passed in, null is returned. -
convert2float
Convert from the passed in instance to a float. If null is passed in, 0.0f is returned. -
convertToFloat
Convert from the passed in instance to a Float. If null is passed in, null is returned. -
convert2double
Convert from the passed in instance to a double. If null is passed in, 0.0d is returned. -
convertToDouble
Convert from the passed in instance to a Double. If null is passed in, null is returned. -
convert2boolean
Convert from the passed in instance to a boolean. If null is passed in, false is returned. -
convertToBoolean
Convert from the passed in instance to a Boolean. If null is passed in, null is returned. -
convert2AtomicInteger
Convert from the passed in instance to an AtomicInteger. If null is passed in, a new AtomicInteger(0) is returned. -
convertToAtomicInteger
Convert from the passed in instance to an AtomicInteger. If null is passed in, null is returned. -
convert2AtomicLong
Convert from the passed in instance to an AtomicLong. If null is passed in, new AtomicLong(0L) is returned. -
convertToAtomicLong
Convert from the passed in instance to an AtomicLong. If null is passed in, null is returned. -
convert2AtomicBoolean
Convert from the passed in instance to an AtomicBoolean. If null is passed in, new AtomicBoolean(false) is returned. -
convertToAtomicBoolean
Convert from the passed in instance to an AtomicBoolean. If null is passed in, null is returned. -
localDateToMillis
Deprecated.No longer needed - use convert(localDate, long.class)- Parameters:
localDate
- A Java LocalDate- Returns:
- a long representing the localDate as epoch milliseconds (since 1970 Jan 1 at midnight)
-
localDateTimeToMillis
Deprecated.No longer needed - use convert(localDateTime, long.class)- Parameters:
localDateTime
- A Java LocalDateTime- Returns:
- a long representing the localDateTime as epoch milliseconds (since 1970 Jan 1 at midnight)
-
zonedDateTimeToMillis
Deprecated.No longer needed - use convert(ZonedDateTime, long.class)- Parameters:
zonedDateTime
- A Java ZonedDateTime- Returns:
- a long representing the ZonedDateTime as epoch milliseconds (since 1970 Jan 1 at midnight)
-