自定义类型转换 - ConverterRegistry
# 自定义类型转换 - ConverterRegistry
# 1. 由来
Hutool 中的类型转换最初是通过 Convert
工具类实现的,每种类型的转换都是通过静态方法来表示。然而,这种方式的扩展性较差,无法满足所有可能的类型转换需求。因此,Hutool 引入了 ConverterRegistry
,用于管理类型转换器并提供更灵活的类型转换机制。
# 2. 解决方案
为了提升扩展性,Hutool 提供了以下解决方案:
Converter
接口:这是一个类型转换接口。通过实现这个接口并重写其convert
方法,可以自定义对象的类型转换逻辑。ConverterRegistry
类型转换登记中心:这是一个管理所有类型转换器的中心。ConverterRegistry
存储了 Hutool 中的默认转换器和用户自定义的转换器。通过ConverterRegistry
的convert
方法,可以自动查找目标类型的转换器,并将对象转换为指定类型。
# 2.1 示例代码
int a = 3423;
ConverterRegistry converterRegistry = ConverterRegistry.getInstance(); // 获取 ConverterRegistry 的单例实例
String result = converterRegistry.convert(String.class, a); // 将整数 a 转换为字符串
Assert.assertEquals("3423", result); // 断言结果为 "3423"
2
3
4
API 使用说明
ConverterRegistry.getInstance()
:- 作用:返回
ConverterRegistry
的单例实例。此方法保证全局只有一个ConverterRegistry
实例,所有类型转换都通过这个实例管理。 - 语法:
ConverterRegistry.getInstance()
- 参数:无。
- 返回值:返回
ConverterRegistry
的单例实例。
- 作用:返回
convert(Class<T> type, Object value)
:- 作用:将
value
转换为指定的type
类型。 - 语法:
<T> T convert(Class<T> type, Object value)
- 参数:
type
:目标类型的Class
对象。例如,String.class
。value
:要转换的对象。
- 返回值:转换后的对象,类型为
T
。
- 作用:将
# 2.2 实际开发中的应用
在实际开发中,ConverterRegistry
非常适合用于将一种类型的对象动态转换为另一种类型。例如,将数据库字段值转换为 Java 对象的属性值,或者在多层架构中进行对象跨层转换。
public class Application {
public static void main(String[] args) {
ConverterRegistry converterRegistry = ConverterRegistry.getInstance();
// 将整数转换为字符串
int userId = 12345;
String userIdStr = converterRegistry.convert(String.class, userId);
// 将字符串转换为 URL
String urlString = "https://example.com";
URL url = converterRegistry.convert(URL.class, urlString);
// 进行业务操作
System.out.println("用户 ID:" + userIdStr);
System.out.println("URL:" + url);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3. 自定义转换
Hutool 提供了许多默认的类型转换器,但在某些情况下,我们可能需要自定义转换逻辑。可以使用 ConverterRegistry.getInstance().putCustom()
方法来自定义类型转换。
# 3.1 自定义转换器
# 定义自定义转换器
首先,我们定义一个实现 Converter
接口的自定义转换器。在这个例子中,我们将自定义一个将对象转换为特定格式字符串的转换器。
public static class CustomConverter implements Converter<String> {
@Override
public String convert(Object value, String defaultValue) throws IllegalArgumentException {
// 将对象转换为自定义格式的字符串
return "Custom: " + value.toString();
}
}
2
3
4
5
6
7
API 使用说明
Converter
接口:- 作用:提供一个标准的类型转换接口。通过实现这个接口,可以自定义任意类型的转换逻辑。
- 语法:
public interface Converter<T>
- 主要方法:
T convert(Object value, T defaultValue)
:- 作用:将
value
转换为类型T
,如果转换失败则返回defaultValue
。 - 语法:
T convert(Object value, T defaultValue)
- 参数:
value
:要转换的对象。defaultValue
:转换失败时返回的默认值。
- 返回值:转换后的对象,类型为
T
。
- 作用:将
# 注册转换器
然后,我们将自定义的转换器注册到 ConverterRegistry
中。
ConverterRegistry converterRegistry = ConverterRegistry.getInstance();
// 自定义 String 类型的转换器
converterRegistry.putCustom(String.class, CustomConverter.class);
2
3
API 使用说明
putCustom(Class<T> type, Class<? extends Converter<T>> converterClass)
:- 作用:将自定义的转换器注册到
ConverterRegistry
中,以处理指定类型的转换。 - 语法:
<T> void putCustom(Class<T> type, Class<? extends Converter<T>> converterClass)
- 参数:
type
:目标类型的Class
对象。例如,String.class
。converterClass
:自定义转换器的Class
对象。例如,CustomConverter.class
。
- 返回值:无。
- 作用:将自定义的转换器注册到
# 执行转换
最后,使用自定义转换器进行类型转换。
int a = 454553;
// 使用自定义转换器将整数 a 转换为字符串
String result = converterRegistry.convert(String.class, a);
Assert.assertEquals("Custom: 454553", result);
2
3
4
API 使用说明
convert(Class<T> type, Object value)
:- 作用:使用已注册的转换器将
value
转换为指定的type
类型。如果自定义转换器已经注册,会优先使用自定义转换器。 - 语法:
<T> T convert(Class<T> type, Object value)
- 参数:
type
:目标类型的Class
对象。例如,String.class
。value
:要转换的对象。
- 返回值:转换后的对象,类型为
T
。
- 作用:使用已注册的转换器将
# 3.2 实际开发中的应用
在实际开发中,自定义转换器可以用于将数据转换为特定格式,以便在系统中更容易使用。例如,将日志数据转换为特定格式的字符串用于输出或存储。
public class Application {
public static void main(String[] args) {
// 获取 ConverterRegistry 实例
ConverterRegistry converterRegistry = ConverterRegistry.getInstance();
// 自定义转换器
converterRegistry.putCustom(String.class, CustomConverter.class);
// 使用自定义转换器将整数转换为特定格式的字符串
int logId = 67890;
String formattedLogId = converterRegistry.convert(String.class, logId);
// 输出或存储格式化后的日志 ID
System.out.println("格式化后的日志 ID:" + formattedLogId);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4. ConverterRegistry
单例和对象模式
ConverterRegistry
提供了一个静态方法 getInstance()
来返回全局单例对象,这是推荐的使用方式。然而,如果你希望在某个限定范围内自定义转换,你也可以实例化 ConverterRegistry
对象。
# 4.1 示例代码
使用全局单例
ConverterRegistry converterRegistry = ConverterRegistry.getInstance(); // 获取全局单例
1使用实例对象
ConverterRegistry customRegistry = new ConverterRegistry(); // 实例化对象
1
API 使用说明
ConverterRegistry.getInstance()
:- 作用:返回
ConverterRegistry
的全局单例实例,保证全局只有一个实例用于类型转换。 - 语法:
ConverterRegistry.getInstance()
- 参数:无。
- 返回值:
ConverterRegistry
的单例实例。
- 作用:返回
new ConverterRegistry()
:- 作用:实例化一个新的
ConverterRegistry
对象,用于在特定范围内管理类型转换。 - 语法:
new ConverterRegistry()
- 参数:无。
- 返回值:一个新的
ConverterRegistry
实例。
- 作用:实例化一个新的
# 4.2 实际开发中的应用
在大多数情况下,使用 ConverterRegistry
的单例模式即可满足需求,尤其是在需要全局统一管理类型转换的场景中。对于局部的、特定场景的类型转换需求,可以实例化 ConverterRegistry
对象来管理这些转换逻辑。
public class Application {
public static void main(String[] args) {
// 使用全局单例进行通用转换
ConverterRegistry globalRegistry = ConverterRegistry.getInstance();
String globalResult = globalRegistry.convert(String.class, 123);
// 使用自定义实例进行特定转换
ConverterRegistry localRegistry = new ConverterRegistry();
localRegistry.putCustom(String.class, CustomConverter.class);
String localResult = localRegistry.convert(String.class, 456);
System.out.println("全局转换结果:" + globalResult);
System.out.println("局部转换结果:" + localResult);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
总结
ConverterRegistry
提供了灵活的类型转换机制。通过自定义转换器,可以轻松实现特定的类型转换需求。结合单例和实例对象的使用方式,ConverterRegistry
可以很好地适应各种开发场景,简化类型转换逻辑,提高代码的可维护性和扩展性。