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);
Module Dependencies:
-
SQL support: Conversions involving
java.sql.Date
andjava.sql.Timestamp
require thejava.sql
module to be present at runtime. If you're using OSGi, ensure your bundle imports thejava.sql
package or declare it as an optional import if SQL support is not required. -
XML support: This library does not directly use XML classes, but
IOUtilities
provides XML stream support that requires thejava.xml
module. SeeIOUtilities
for more details.
- 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.
-
Nested Class Summary
Nested Classes -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionConverter
(ConverterOptions options) Constructs a new Converter instance with the specified options. -
Method Summary
Modifier and TypeMethodDescriptionConvert<?>
addConversion
(Convert<?> conversionMethod, Class<?> source, Class<?> target) Adds a new conversion function for converting from one type to another for this specific Converter instance.Convert<?>
addConversion
(Class<?> source, Class<?> target, Convert<?> conversionMethod) Deprecated.Retrieves a map of all supported conversions, categorized by source and target classes.<T> T
Converts the given source object to the specified target type.Retrieves the converter options associated with this Converter instance.Retrieves a map of all supported conversions with class names instead of class objects.static <T> T
Performs an identity conversion, returning the source object as-is.static boolean
isCollectionConversionSupported
(Class<?> sourceType, Class<?> target) Deprecated.UseisContainerConversionSupported(Class, Class)
instead.static boolean
isContainerConversionSupported
(Class<?> sourceType, Class<?> target) Determines if a container-based conversion is supported between the specified source and target types.boolean
isConversionSupportedFor
(Class<?> type) Overload ofisConversionSupportedFor(Class, Class)
that checks whether the specified class can be converted to itself.boolean
isConversionSupportedFor
(Class<?> source, Class<?> target) Determines whether a conversion from the specified source type to the target type is supported.boolean
isSimpleTypeConversionSupported
(Class<?> type) Overload ofisSimpleTypeConversionSupported(Class, Class)
that checks if the specified class is considered a simple type.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 Converter.ConversionPair
static Converter.ConversionPair
-
Field Details
-
PRECISION_MILLIS
- See Also:
-
PRECISION_NANOS
- See Also:
-
-
Constructor Details
-
Converter
Constructs a new Converter instance with the specified options.The Converter initializes its internal conversion databases by merging the predefined
CONVERSION_DB
with any user-specified overrides provided inoptions
.- Parameters:
options
- TheConverterOptions
that configure this Converter's behavior and conversions.- Throws:
NullPointerException
- ifoptions
isnull
.
-
-
Method Details
-
pair
-
pair
-
getOptions
Retrieves the converter options associated with this Converter instance.- Returns:
- The
ConverterOptions
used by this Converter.
-
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); LOG.info("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); LOG.info("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); LOG.info("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); LOG.info("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); LOG.info("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); LOG.info("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 achieved 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 the 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,
-
isContainerConversionSupported
Determines if a container-based conversion is supported between the specified source and target types. This method checks for valid conversions between arrays, collections, Maps, and EnumSets without actually performing the conversion.Supported conversions include:
- Array to Collection
- Collection to Array
- Array to Array (when component types differ)
- Array, Collection, or Map to EnumSet (when target is an Enum type)
- EnumSet to Array or Collection
- Parameters:
sourceType
- The source type to convert fromtarget
- The target type to convert to- Returns:
- true if a container-based conversion is supported between the types, false otherwise
- Throws:
IllegalArgumentException
- if target is EnumSet.class (caller should specify specific Enum type instead)
-
isCollectionConversionSupported
@Deprecated public static boolean isCollectionConversionSupported(Class<?> sourceType, Class<?> target) Deprecated.UseisContainerConversionSupported(Class, Class)
instead. This method will be removed in a future version. -
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:
Converter converter = new Converter(options); // Check if String can be converted to Integer boolean canConvert = converter.isNonCollectionConversionSupportedFor( String.class, Integer.class); // returns true // Check array conversion (always returns false) boolean arrayConvert = converter.isNonCollectionConversionSupportedFor( String[].class, Integer[].class); // returns false // Check collection conversion (always returns false) boolean listConvert = converter.isNonCollectionConversionSupportedFor( 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:
-
isSimpleTypeConversionSupported
Overload ofisSimpleTypeConversionSupported(Class, Class)
that checks if the specified class is considered a simple type. Results are cached for fast subsequent lookups when no custom overrides exist.If custom converter overrides exist for the specified type, this method returns false, regardless of inheritance-based conversion support. This ensures that user-defined custom converters take precedence over automatic simple type conversions.
- Parameters:
type
- the class to check- Returns:
true
if a simple type conversion exists for the class and no custom overrides are registered
-
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
-
isConversionSupportedFor
Overload ofisConversionSupportedFor(Class, Class)
that checks whether the specified class can be converted to itself. The result is cached for fast repeat access.- Parameters:
type
- the class to query- Returns:
true
if a conversion exists for the class
-
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 (built-in) 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 (built-int) conversions by class names.
-
addConversion
@Deprecated public Convert<?> addConversion(Class<?> source, Class<?> target, Convert<?> conversionMethod) Deprecated.UseaddConversion(Convert, Class, Class)
instead. This method will be removed in a future version as it is less safe and does not handle all type variations correctly.- Parameters:
conversionMethod
- A method that converts an instance of the source type to an instance of the target type.- Returns:
- The previous conversion method associated with the source and target types, or
null
if no conversion existed.
-
addConversion
Adds a new conversion function for converting from one type to another for this specific Converter instance.When
convert(source, target)
is called on this instance, the conversion function is located by:- Checking instance-specific conversions first (added via this method)
- Checking factory conversions (built-in conversions)
- Attempting inheritance-based conversion lookup
This method automatically handles primitive types by converting them to their corresponding wrapper types and stores conversions for all primitive/wrapper combinations, just like the static version.
- Parameters:
conversionMethod
- A method that converts an instance of the source type to an instance of the target type.source
- The source class (type) to convert from.target
- The target class (type) to convert to.- Returns:
- The previous conversion method associated with the source and target types for this instance, or
null
if no conversion existed.
-
identity
Performs an identity conversion, returning the source object as-is.- Type Parameters:
T
- The type of the source and target object.- Parameters:
from
- The source object.converter
- The Converter instance performing the conversion.- Returns:
- The source object unchanged.
-
addConversion(Convert, Class, Class)
instead.