Hutool工具类

本文详细介绍了Hutool工具库中的Console类,提供了一系列方便的控制台输出方法。此外,还探讨了Converter接口和ConverterRegistry类,它们在类型转换中起到关键作用,支持多种数据类型的转换。Console类提供了如log、print、error等方法,Converter接口定义了转换器的基本操作,而ConverterRegistry负责管理和查找转换器。
摘要由CSDN通过智能技术生成

core模块

Console

package cn.hutool.core.lang;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;

import java.util.Scanner;

import static java.lang.System.err;
import static java.lang.System.out;

/**
 * 命令行(控制台)工具方法类<br>
 * 此类主要针对{@link System#out} 和 {@link System#err} 做封装。
 *
 * @author Looly
 */

public class Console {

	private static final String TEMPLATE_VAR = "{}";

	// --------------------------------------------------------------------------------- Log

	/**
	 * 同 System.out.println()方法,打印控制台日志
	 */
	public static void log() {
		out.println();
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志<br>
	 * 如果传入打印对象为{@link Throwable}对象,那么同时打印堆栈
	 *
	 * @param obj 要打印的对象
	 */
	public static void log(Object obj) {
		if (obj instanceof Throwable) {
			final Throwable e = (Throwable) obj;
			log(e, e.getMessage());
		} else {
			log(TEMPLATE_VAR, obj);
		}
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志<br>
	 * 如果传入打印对象为{@link Throwable}对象,那么同时打印堆栈
	 *
	 * @param obj1      第一个要打印的对象
	 * @param otherObjs 其它要打印的对象
	 * @since 5.4.3
	 */
	public static void log(Object obj1, Object... otherObjs) {
		if (ArrayUtil.isEmpty(otherObjs)) {
			log(obj1);
		} else {
			log(buildTemplateSplitBySpace(otherObjs.length + 1), ArrayUtil.insert(otherObjs, 0, obj1));
		}
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志<br>
	 * 当传入template无"{}"时,被认为非模板,直接打印多个参数以空格分隔
	 *
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 */
	public static void log(String template, Object... values) {
		if (ArrayUtil.isEmpty(values) || StrUtil.contains(template, TEMPLATE_VAR)) {
			logInternal(template, values);
		} else {
			logInternal(buildTemplateSplitBySpace(values.length + 1), ArrayUtil.insert(values, 0, template));
		}
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志
	 *
	 * @param t        异常对象
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 */
	public static void log(Throwable t, String template, Object... values) {
		out.println(StrUtil.format(template, values));
		if (null != t) {
			//noinspection CallToPrintStackTrace
			t.printStackTrace();
			out.flush();
		}
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志
	 *
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 * @since 5.4.3
	 */
	private static void logInternal(String template, Object... values) {
		log(null, template, values);
	}

	// --------------------------------------------------------------------------------- print

	/**
	 * 打印表格到控制台
	 *
	 * @param consoleTable 控制台表格
	 * @since 5.4.5
	 */
	public static void table(ConsoleTable consoleTable) {
		print(consoleTable.toString());
	}

	/**
	 * 同 System.out.print()方法,打印控制台日志
	 *
	 * @param obj 要打印的对象
	 * @since 3.3.1
	 */
	public static void print(Object obj) {
		print(TEMPLATE_VAR, obj);
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志<br>
	 * 如果传入打印对象为{@link Throwable}对象,那么同时打印堆栈
	 *
	 * @param obj1      第一个要打印的对象
	 * @param otherObjs 其它要打印的对象
	 * @since 5.4.3
	 */
	public static void print(Object obj1, Object... otherObjs) {
		if (ArrayUtil.isEmpty(otherObjs)) {
			print(obj1);
		} else {
			print(buildTemplateSplitBySpace(otherObjs.length + 1), ArrayUtil.insert(otherObjs, 0, obj1));
		}
	}

	/**
	 * 同 System.out.print()方法,打印控制台日志
	 *
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 * @since 3.3.1
	 */
	public static void print(String template, Object... values) {
		if (ArrayUtil.isEmpty(values) || StrUtil.contains(template, TEMPLATE_VAR)) {
			printInternal(template, values);
		} else {
			printInternal(buildTemplateSplitBySpace(values.length + 1), ArrayUtil.insert(values, 0, template));
		}
	}

	/**
	 * 打印进度条
	 *
	 * @param showChar 进度条提示字符,例如“#”
	 * @param len      打印长度
	 * @since 4.5.6
	 */
	public static void printProgress(char showChar, int len) {
		print("{}{}", CharUtil.CR, StrUtil.repeat(showChar, len));
	}

	/**
	 * 打印进度条
	 *
	 * @param showChar 进度条提示字符,例如“#”
	 * @param totalLen 总长度
	 * @param rate     总长度所占比取值0~1
	 * @since 4.5.6
	 */
	public static void printProgress(char showChar, int totalLen, double rate) {
		Assert.isTrue(rate >= 0 && rate <= 1, "Rate must between 0 and 1 (both include)");
		printProgress(showChar, (int) (totalLen * rate));
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志
	 *
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 * @since 5.4.3
	 */
	private static void printInternal(String template, Object... values) {
		out.print(StrUtil.format(template, values));
	}

	// --------------------------------------------------------------------------------- Error

	/**
	 * 同 System.err.println()方法,打印控制台日志
	 */
	public static void error() {
		err.println();
	}

	/**
	 * 同 System.err.println()方法,打印控制台日志
	 *
	 * @param obj 要打印的对象
	 */
	public static void error(Object obj) {
		if (obj instanceof Throwable) {
			Throwable e = (Throwable) obj;
			error(e, e.getMessage());
		} else {
			error(TEMPLATE_VAR, obj);
		}
	}

	/**
	 * 同 System.out.println()方法,打印控制台日志<br>
	 * 如果传入打印对象为{@link Throwable}对象,那么同时打印堆栈
	 *
	 * @param obj1      第一个要打印的对象
	 * @param otherObjs 其它要打印的对象
	 * @since 5.4.3
	 */
	public static void error(Object obj1, Object... otherObjs) {
		if (ArrayUtil.isEmpty(otherObjs)) {
			error(obj1);
		} else {
			error(buildTemplateSplitBySpace(otherObjs.length + 1), ArrayUtil.insert(otherObjs, 0, obj1));
		}
	}

	/**
	 * 同 System.err.println()方法,打印控制台日志
	 *
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 */
	public static void error(String template, Object... values) {
		if (ArrayUtil.isEmpty(values) || StrUtil.contains(template, TEMPLATE_VAR)) {
			errorInternal(template, values);
		} else {
			errorInternal(buildTemplateSplitBySpace(values.length + 1), ArrayUtil.insert(values, 0, template));
		}
	}

	/**
	 * 同 System.err.println()方法,打印控制台日志
	 *
	 * @param t        异常对象
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 */
	public static void error(Throwable t, String template, Object... values) {
		err.println(StrUtil.format(template, values));
		if (null != t) {
			t.printStackTrace(err);
			err.flush();
		}
	}

	/**
	 * 同 System.err.println()方法,打印控制台日志
	 *
	 * @param template 文本模板,被替换的部分用 {} 表示
	 * @param values   值
	 */
	private static void errorInternal(String template, Object... values) {
		error(null, template, values);
	}

	// --------------------------------------------------------------------------------- in

	/**
	 * 创建从控制台读取内容的{@link Scanner}
	 *
	 * @return {@link Scanner}
	 * @since 3.3.1
	 */
	public static Scanner scanner() {
		return new Scanner(System.in);
	}

	/**
	 * 读取用户输入的内容(在控制台敲回车前的内容)
	 *
	 * @return 用户输入的内容
	 * @since 3.3.1
	 */
	public static String input() {
		return scanner().nextLine();
	}

	// --------------------------------------------------------------------------------- console lineNumber

	/**
	 * 返回当前位置+行号 (不支持Lambda、内部类、递归内使用)
	 *
	 * @return 返回当前行号
	 * @author dahuoyzs
	 * @since 5.2.5
	 */
	public static String where() {
		final StackTraceElement stackTraceElement = new Throwable().getStackTrace()[1];
		final String className = stackTraceElement.getClassName();
		final String methodName = stackTraceElement.getMethodName();
		final String fileName = stackTraceElement.getFileName();
		final Integer lineNumber = stackTraceElement.getLineNumber();
		return String.format("%s.%s(%s:%s)", className, methodName, fileName, lineNumber);
	}

	/**
	 * 返回当前行号 (不支持Lambda、内部类、递归内使用)
	 *
	 * @return 返回当前行号
	 * @since 5.2.5
	 */
	public static Integer lineNumber() {
		return new Throwable().getStackTrace()[1].getLineNumber();
	}

	/**
	 * 构建空格分隔的模板,类似于"{} {} {} {}"
	 *
	 * @param count 变量数量
	 * @return 模板
	 */
	private static String buildTemplateSplitBySpace(int count) {
		return StrUtil.repeatAndJoin(TEMPLATE_VAR, count, StrUtil.SPACE);
	}

}

Converter万能转换器

Converter接口

package cn.hutool.core.convert;

/**
 * 转换器接口,实现类型转换
 *
 * @param <T> 转换到的目标类型
 * @author Looly
 */
public interface Converter<T> {

	/**
	 * 转换为指定类型<br>
	 * 如果类型无法确定,将读取默认值的类型做为目标类型
	 *
	 * @param value 原始值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 * @throws IllegalArgumentException 无法确定目标类型,且默认值为{@code null},无法确定类型
	 */
	T convert(Object value, T defaultValue) throws IllegalArgumentException;

}

Converter

package cn.hutool.core.convert;

import cn.hutool.core.convert.impl.CollectionConverter;
import cn.hutool.core.convert.impl.EnumConverter;
import cn.hutool.core.convert.impl.MapConverter;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 类型转换器
 *
 * @author xiaoleilu
 *
 */
public class Convert {

	/**
	 * 转换为字符串<br>
	 * 如果给定的值为null,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static String toStr(Object value, String defaultValue) {
		return convertQuietly(String.class, value, defaultValue);
	}

	/**
	 * 转换为字符串<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static String toStr(Object value) {
		return toStr(value, null);
	}

	/**
	 * 转换为String数组
	 *
	 * @param value 被转换的值
	 * @return String数组
	 * @since 3.2.0
	 */
	public static String[] toStrArray(Object value) {
		return convert(String[].class, value);
	}

	/**
	 * 转换为字符<br>
	 * 如果给定的值为null,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Character toChar(Object value, Character defaultValue) {
		return convertQuietly(Character.class, value, defaultValue);
	}

	/**
	 * 转换为字符<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Character toChar(Object value) {
		return toChar(value, null);
	}

	/**
	 * 转换为Character数组
	 *
	 * @param value 被转换的值
	 * @return Character数组
	 * @since 3.2.0
	 */
	public static Character[] toCharArray(Object value) {
		return convert(Character[].class, value);
	}

	/**
	 * 转换为byte<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Byte toByte(Object value, Byte defaultValue) {
		return convertQuietly(Byte.class, value, defaultValue);
	}

	/**
	 * 转换为byte<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Byte toByte(Object value) {
		return toByte(value, null);
	}

	/**
	 * 转换为Byte数组
	 *
	 * @param value 被转换的值
	 * @return Byte数组
	 * @since 3.2.0
	 */
	public static Byte[] toByteArray(Object value) {
		return convert(Byte[].class, value);
	}

	/**
	 * 转换为Byte数组
	 *
	 * @param value 被转换的值
	 * @return Byte数组
	 * @since 5.1.1
	 */
	public static byte[] toPrimitiveByteArray(Object value) {
		return convert(byte[].class, value);
	}

	/**
	 * 转换为Short<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Short toShort(Object value, Short defaultValue) {
		return convertQuietly(Short.class, value, defaultValue);
	}

	/**
	 * 转换为Short<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Short toShort(Object value) {
		return toShort(value, null);
	}

	/**
	 * 转换为Short数组
	 *
	 * @param value 被转换的值
	 * @return Short数组
	 * @since 3.2.0
	 */
	public static Short[] toShortArray(Object value) {
		return convert(Short[].class, value);
	}

	/**
	 * 转换为Number<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Number toNumber(Object value, Number defaultValue) {
		return convertQuietly(Number.class, value, defaultValue);
	}

	/**
	 * 转换为Number<br>
	 * 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Number toNumber(Object value) {
		return toNumber(value, null);
	}

	/**
	 * 转换为Number数组
	 *
	 * @param value 被转换的值
	 * @return Number数组
	 * @since 3.2.0
	 */
	public static Number[] toNumberArray(Object value) {
		return convert(Number[].class, value);
	}

	/**
	 * 转换为int<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Integer toInt(Object value, Integer defaultValue) {
		return convertQuietly(Integer.class, value, defaultValue);
	}

	/**
	 * 转换为int<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Integer toInt(Object value) {
		return toInt(value, null);
	}

	/**
	 * 转换为Integer数组<br>
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Integer[] toIntArray(Object value) {
		return convert(Integer[].class, value);
	}

	/**
	 * 转换为long<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Long toLong(Object value, Long defaultValue) {
		return convertQuietly(Long.class, value, defaultValue);
	}

	/**
	 * 转换为long<br>
	 * 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Long toLong(Object value) {
		return toLong(value, null);
	}

	/**
	 * 转换为Long数组<br>
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Long[] toLongArray(Object value) {
		return convert(Long[].class, value);
	}

	/**
	 * 转换为double<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Double toDouble(Object value, Double defaultValue) {
		return convertQuietly(Double.class, value, defaultValue);
	}

	/**
	 * 转换为double<br>
	 * 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Double toDouble(Object value) {
		return toDouble(value, null);
	}

	/**
	 * 转换为Double数组<br>
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Double[] toDoubleArray(Object value) {
		return convert(Double[].class, value);
	}

	/**
	 * 转换为Float<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Float toFloat(Object value, Float defaultValue) {
		return convertQuietly(Float.class, value, defaultValue);
	}

	/**
	 * 转换为Float<br>
	 * 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Float toFloat(Object value) {
		return toFloat(value, null);
	}

	/**
	 * 转换为Float数组<br>
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Float[] toFloatArray(Object value) {
		return convert(Float[].class, value);
	}

	/**
	 * 转换为boolean<br>
	 * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Boolean toBool(Object value, Boolean defaultValue) {
		return convertQuietly(Boolean.class, value, defaultValue);
	}

	/**
	 * 转换为boolean<br>
	 * 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Boolean toBool(Object value) {
		return toBool(value, null);
	}

	/**
	 * 转换为Boolean数组<br>
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Boolean[] toBooleanArray(Object value) {
		return convert(Boolean[].class, value);
	}

	/**
	 * 转换为BigInteger<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static BigInteger toBigInteger(Object value, BigInteger defaultValue) {
		return convertQuietly(BigInteger.class, value, defaultValue);
	}

	/**
	 * 转换为BigInteger<br>
	 * 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static BigInteger toBigInteger(Object value) {
		return toBigInteger(value, null);
	}

	/**
	 * 转换为BigDecimal<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
		return convertQuietly(BigDecimal.class, value, defaultValue);
	}

	/**
	 * 转换为BigDecimal<br>
	 * 如果给定的值为空,或者转换失败,返回null<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static BigDecimal toBigDecimal(Object value) {
		return toBigDecimal(value, null);
	}

	/**
	 * 转换为Date<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 * @since 4.1.6
	 */
	public static Date toDate(Object value, Date defaultValue) {
		return convertQuietly(Date.class, value, defaultValue);
	}

	/**
	 * LocalDateTime<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 * @since 5.0.7
	 */
	public static LocalDateTime toLocalDateTime(Object value, LocalDateTime defaultValue) {
		return convertQuietly(LocalDateTime.class, value, defaultValue);
	}

	/**
	 * 转换为LocalDateTime<br>
	 * 如果给定的值为空,或者转换失败,返回{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static LocalDateTime toLocalDateTime(Object value) {
		return toLocalDateTime(value, null);
	}

	/**
	 * Instant<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 * @since 5.0.7
	 */
	public static Date toInstant(Object value, Date defaultValue) {
		return convertQuietly(Instant.class, value, defaultValue);
	}

	/**
	 * 转换为Date<br>
	 * 如果给定的值为空,或者转换失败,返回{@code null}<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 * @since 4.1.6
	 */
	public static Date toDate(Object value) {
		return toDate(value, null);
	}

	/**
	 * 转换为Enum对象<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 *
	 * @param <E> 枚举类型
	 * @param clazz Enum的Class
	 * @param value 值
	 * @param defaultValue 默认值
	 * @return Enum
	 */
	@SuppressWarnings("unchecked")
	public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) {
		return (E) (new EnumConverter(clazz)).convertQuietly(value, defaultValue);
	}

	/**
	 * 转换为Enum对象<br>
	 * 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
	 *
	 * @param <E> 枚举类型
	 * @param clazz Enum的Class
	 * @param value 值
	 * @return Enum
	 */
	public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) {
		return toEnum(clazz, value, null);
	}

	/**
	 * 转换为集合类
	 *
	 * @param collectionType 集合类型
	 * @param elementType 集合中元素类型
	 * @param value 被转换的值
	 * @return {@link Collection}
	 * @since 3.0.8
	 */
	public static Collection<?> toCollection(Class<?> collectionType, Class<?> elementType, Object value) {
		return new CollectionConverter(collectionType, elementType).convert(value, null);
	}

	/**
	 * 转换为ArrayList,元素类型默认Object
	 *
	 * @param value 被转换的值
	 * @return {@link List}
	 * @since 4.1.11
	 */
	public static List<?> toList(Object value) {
		return convert(List.class, value);
	}

	/**
	 * 转换为ArrayList
	 *
	 * @param <T> 元素类型
	 * @param elementType 集合中元素类型
	 * @param value 被转换的值
	 * @return {@link ArrayList}
	 * @since 4.1.20
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> toList(Class<T> elementType, Object value) {
		return (List<T>) toCollection(ArrayList.class, elementType, value);
	}

	/**
	 * 转换为HashSet
	 *
	 * @param <T> 元素类型
	 * @param elementType 集合中元素类型
	 * @param value 被转换的值
	 * @return {@link HashSet}
	 * @since 5.7.3
	 */
	@SuppressWarnings("unchecked")
	public static <T> Set<T> toSet(Class<T> elementType, Object value) {
		return (Set<T>) toCollection(HashSet.class, elementType, value);
	}

	/**
	 * 转换为Map
	 *
	 * @param <K> 键类型
	 * @param <V> 值类型
	 * @param keyType 键类型
	 * @param valueType 值类型
	 * @param value 被转换的值
	 * @return {@link Map}
	 * @since 4.6.8
	 */
	@SuppressWarnings("unchecked")
	public static <K, V> Map<K, V> toMap(Class<K> keyType, Class<V> valueType, Object value) {
		return (Map<K, V>) new MapConverter(HashMap.class, keyType, valueType).convert(value, null);
	}

	/**
	 * 转换值为指定类型,类型采用字符串表示
	 *
	 * @param <T> 目标类型
	 * @param className 类的字符串表示
	 * @param value 值
	 * @return 转换后的值
	 * @since 4.0.7
	 * @throws ConvertException 转换器不存在
	 */
	public static <T> T convertByClassName(String className, Object value) throws ConvertException{
		return convert(ClassUtil.loadClass(className), value);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T> 目标类型
	 * @param type 类型
	 * @param value 值
	 * @return 转换后的值
	 * @since 4.0.0
	 * @throws ConvertException 转换器不存在
	 */
	public static <T> T convert(Class<T> type, Object value) throws ConvertException{
		return convert((Type)type, value);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T> 目标类型
	 * @param reference 类型参考,用于持有转换后的泛型类型
	 * @param value 值
	 * @return 转换后的值
	 * @throws ConvertException 转换器不存在
	 */
	public static <T> T convert(TypeReference<T> reference, Object value) throws ConvertException{
		return convert(reference.getType(), value, null);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T> 目标类型
	 * @param type 类型
	 * @param value 值
	 * @return 转换后的值
	 * @throws ConvertException 转换器不存在
	 */
	public static <T> T convert(Type type, Object value) throws ConvertException{
		return convert(type, value, null);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T> 目标类型
	 * @param type 类型
	 * @param value 值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 * @throws ConvertException 转换器不存在
	 * @since 4.0.0
	 */
	public static <T> T convert(Class<T> type, Object value, T defaultValue) throws ConvertException {
		return convert((Type)type, value, defaultValue);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T> 目标类型
	 * @param type 类型
	 * @param value 值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 * @throws ConvertException 转换器不存在
	 */
	public static <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
		return convertWithCheck(type, value, defaultValue, false);
	}

	/**
	 * 转换值为指定类型,不抛异常转换<br>
	 * 当转换失败时返回{@code null}
	 *
	 * @param <T> 目标类型
	 * @param type 目标类型
	 * @param value 值
	 * @return 转换后的值,转换失败返回null
	 * @since 4.5.10
	 */
	public static <T> T convertQuietly(Type type, Object value) {
		return convertQuietly(type, value, null);
	}

	/**
	 * 转换值为指定类型,不抛异常转换<br>
	 * 当转换失败时返回默认值
	 *
	 * @param <T> 目标类型
	 * @param type 目标类型
	 * @param value 值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 * @since 4.5.10
	 */
	public static <T> T convertQuietly(Type type, Object value, T defaultValue) {
		return convertWithCheck(type, value, defaultValue, true);
	}

	/**
	 * 转换值为指定类型,可选是否不抛异常转换<br>
	 * 当转换失败时返回默认值
	 *
	 * @param <T> 目标类型
	 * @param type 目标类型
	 * @param value 值
	 * @param defaultValue 默认值
	 * @param quietly 是否静默转换,true不抛异常
	 * @return 转换后的值
	 * @since 5.3.2
	 */
	public static <T> T convertWithCheck(Type type, Object value, T defaultValue, boolean quietly) {
		final ConverterRegistry registry = ConverterRegistry.getInstance();
		try {
			return registry.convert(type, value, defaultValue);
		} catch (Exception e) {
			if(quietly){
				return defaultValue;
			}
			throw e;
		}
	}

	// ----------------------------------------------------------------------- 全角半角转换
	/**
	 * 半角转全角
	 *
	 * @param input String.
	 * @return 全角字符串.
	 */
	public static String toSBC(String input) {
		return toSBC(input, null);
	}

	/**
	 * 半角转全角
	 *
	 * @param input String
	 * @param notConvertSet 不替换的字符集合
	 * @return 全角字符串.
	 */
	public static String toSBC(String input, Set<Character> notConvertSet) {
		final char[] c = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (null != notConvertSet && notConvertSet.contains(c[i])) {
				// 跳过不替换的字符
				continue;
			}

			if (c[i] == ' ') {
				c[i] = '\u3000';
			} else if (c[i] < '\177') {
				c[i] = (char) (c[i] + 65248);

			}
		}
		return new String(c);
	}

	/**
	 * 全角转半角
	 *
	 * @param input String.
	 * @return 半角字符串
	 */
	public static String toDBC(String input) {
		return toDBC(input, null);
	}

	/**
	 * 替换全角为半角
	 *
	 * @param text 文本
	 * @param notConvertSet 不替换的字符集合
	 * @return 替换后的字符
	 */
	public static String toDBC(String text, Set<Character> notConvertSet) {
		if(StrUtil.isBlank(text)) {
			return text;
		}
		final char[] c = text.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (null != notConvertSet && notConvertSet.contains(c[i])) {
				// 跳过不替换的字符
				continue;
			}

			if (c[i] == '\u3000' || c[i] == '\u00a0' || c[i] == '\u2007' || c[i] == '\u202F') {
				// \u3000是中文全角空格,\u00a0、\u2007、\u202F是不间断空格
				c[i] = ' ';
			} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
				c[i] = (char) (c[i] - 65248);
			}
		}

		return new String(c);
	}

	// --------------------------------------------------------------------- hex
	/**
	 * 字符串转换成十六进制字符串,结果为小写
	 *
	 * @param str 待转换的ASCII字符串
	 * @param charset 编码
	 * @return 16进制字符串
	 * @see HexUtil#encodeHexStr(String, Charset)
	 */
	public static String toHex(String str, Charset charset) {
		return HexUtil.encodeHexStr(str, charset);
	}

	/**
	 * byte数组转16进制串
	 *
	 * @param bytes 被转换的byte数组
	 * @return 转换后的值
	 * @see HexUtil#encodeHexStr(byte[])
	 */
	public static String toHex(byte[] bytes) {
		return HexUtil.encodeHexStr(bytes);
	}

	/**
	 * Hex字符串转换为Byte值
	 *
	 * @param src Byte字符串,每个Byte之间没有分隔符
	 * @return byte[]
	 * @see HexUtil#decodeHex(char[])
	 */
	public static byte[] hexToBytes(String src) {
		return HexUtil.decodeHex(src.toCharArray());
	}

	/**
	 * 十六进制转换字符串
	 *
	 * @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
	 * @param charset 编码 {@link Charset}
	 * @return 对应的字符串
	 * @see HexUtil#decodeHexStr(String, Charset)
	 * @since 4.1.11
	 */
	public static String hexToStr(String hexStr, Charset charset) {
		return HexUtil.decodeHexStr(hexStr, charset);
	}

	/**
	 * String的字符串转换成unicode的String
	 *
	 * @param strText 全角字符串
	 * @return String 每个unicode之间无分隔符
	 * @see UnicodeUtil#toUnicode(String)
	 */
	public static String strToUnicode(String strText) {
		return UnicodeUtil.toUnicode(strText);
	}

	/**
	 * unicode的String转换成String的字符串
	 *
	 * @param unicode Unicode符
	 * @return String 字符串
	 * @see UnicodeUtil#toString(String)
	 */
	public static String unicodeToStr(String unicode) {
		return UnicodeUtil.toString(unicode);
	}

	/**
	 * 给定字符串转换字符编码<br>
	 * 如果参数为空,则返回原字符串,不报错。
	 *
	 * @param str 被转码的字符串
	 * @param sourceCharset 原字符集
	 * @param destCharset 目标字符集
	 * @return 转换后的字符串
	 * @see CharsetUtil#convert(String, String, String)
	 */
	public static String convertCharset(String str, String sourceCharset, String destCharset) {
		if (StrUtil.hasBlank(str, sourceCharset, destCharset)) {
			return str;
		}

		return CharsetUtil.convert(str, sourceCharset, destCharset);
	}

	/**
	 * 转换时间单位
	 *
	 * @param sourceDuration 时长
	 * @param sourceUnit 源单位
	 * @param destUnit 目标单位
	 * @return 目标单位的时长
	 */
	public static long convertTime(long sourceDuration, TimeUnit sourceUnit, TimeUnit destUnit) {
		Assert.notNull(sourceUnit, "sourceUnit is null !");
		Assert.notNull(destUnit, "destUnit is null !");
		return destUnit.convert(sourceDuration, sourceUnit);
	}

	// --------------------------------------------------------------- 原始包装类型转换
	/**
	 * 原始类转为包装类,非原始类返回原类
	 *
	 * @see BasicType#wrap(Class)
	 * @param clazz 原始类
	 * @return 包装类
	 * @see BasicType#wrap(Class)
	 */
	public static Class<?> wrap(Class<?> clazz) {
		return BasicType.wrap(clazz);
	}

	/**
	 * 包装类转为原始类,非包装类返回原类
	 *
	 * @see BasicType#unWrap(Class)
	 * @param clazz 包装类
	 * @return 原始类
	 * @see BasicType#unWrap(Class)
	 */
	public static Class<?> unWrap(Class<?> clazz) {
		return BasicType.unWrap(clazz);
	}

	// -------------------------------------------------------------------------- 数字和英文转换
	/**
	 * 将阿拉伯数字转为英文表达方式
	 *
	 * @param number {@link Number}对象
	 * @return 英文表达式
	 * @since 3.0.9
	 */
	public static String numberToWord(Number number) {
		return NumberWordFormatter.format(number);
	}

	/**
	 * 将阿拉伯数字转为精简表示形式,例如:
	 *
	 * <pre>
	 *     1200 -》 1.2k
	 * </pre>
	 *
	 * @param number {@link Number}对象
	 * @return 英文表达式
	 * @since 5.5.9
	 */
	public static String numberToSimple(Number number) {
		return NumberWordFormatter.formatSimple(number.longValue());
	}

	/**
	 * 将阿拉伯数字转为中文表达方式
	 *
	 * @param number 数字
	 * @param isUseTraditional 是否使用繁体字(金额形式)
	 * @return 中文
	 * @since 3.2.3
	 */
	public static String numberToChinese(double number, boolean isUseTraditional) {
		return NumberChineseFormatter.format(number, isUseTraditional);
	}

	/**
	 * 数字中文表示形式转数字
	 * <ul>
	 *     <li>一百一十二 -》 112</li>
	 *     <li>一千零一十二 -》 1012</li>
	 * </ul>
	 *
	 * @param number 数字中文表示
	 * @return 数字
	 * @since 5.6.0
	 */
	public static int chineseToNumber(String number){
		return NumberChineseFormatter.chineseToNumber(number);
	}

	/**
	 * 金额转为中文形式
	 *
	 * @param n 数字
	 * @return 中文大写数字
	 * @since 3.2.3
	 */
	public static String digitToChinese(Number n) {
		if(null == n) {
			return "零";
		}
		return NumberChineseFormatter.format(n.doubleValue(), true, true);
	}

	// -------------------------------------------------------------------------- 数字转换
	/**
	 * int转byte
	 *
	 * @param intValue int值
	 * @return byte值
	 * @since 3.2.0
	 */
	public static byte intToByte(int intValue) {
		return (byte) intValue;
	}

	/**
	 * byte转无符号int
	 *
	 * @param byteValue byte值
	 * @return 无符号int值
	 * @since 3.2.0
	 */
	public static int byteToUnsignedInt(byte byteValue) {
		// Java 总是把 byte 当做有符处理;我们可以通过将其和 0xFF 进行二进制与得到它的无符值
		return byteValue & 0xFF;
	}

	/**
	 * byte数组转short<br>
	 * 默认以小端序转换
	 *
	 * @param bytes byte数组
	 * @return short值
	 * @since 5.6.3
	 */
	public static short bytesToShort(byte[] bytes) {
		return ByteUtil.bytesToShort(bytes);
	}

	/**
	 * short转byte数组<br>
	 * 默认以小端序转换
	 *
	 * @param shortValue short值
	 * @return byte数组
	 * @since 5.6.3
	 */
	public static byte[] shortToBytes(short shortValue) {
		return ByteUtil.shortToBytes(shortValue);
	}

	/**
	 * byte[]转int值<br>
	 * 默认以小端序转换
	 *
	 * @param bytes byte数组
	 * @return int值
	 * @since 5.6.3
	 */
	public static int bytesToInt(byte[] bytes) {
		return ByteUtil.bytesToInt(bytes);
	}

	/**
	 * int转byte数组<br>
	 * 默认以小端序转换
	 *
	 * @param intValue int值
	 * @return byte数组
	 * @since 5.6.3
	 */
	public static byte[] intToBytes(int intValue) {
		return ByteUtil.intToBytes(intValue);
	}

	/**
	 * long转byte数组<br>
	 * 默认以小端序转换<br>
	 * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
	 *
	 * @param longValue long值
	 * @return byte数组
	 * @since 5.6.3
	 */
	public static byte[] longToBytes(long longValue) {
		return ByteUtil.longToBytes(longValue);
	}

	/**
	 * byte数组转long<br>
	 * 默认以小端序转换<br>
	 * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
	 *
	 * @param bytes byte数组
	 * @return long值
	 * @since 5.6.3
	 */
	public static long bytesToLong(byte[] bytes) {
		return ByteUtil.bytesToLong(bytes);
	}
}

ConverterRegistry

package cn.hutool.core.convert;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.impl.ArrayConverter;
import cn.hutool.core.convert.impl.AtomicBooleanConverter;
import cn.hutool.core.convert.impl.AtomicIntegerArrayConverter;
import cn.hutool.core.convert.impl.AtomicLongArrayConverter;
import cn.hutool.core.convert.impl.AtomicReferenceConverter;
import cn.hutool.core.convert.impl.BeanConverter;
import cn.hutool.core.convert.impl.BooleanConverter;
import cn.hutool.core.convert.impl.CalendarConverter;
import cn.hutool.core.convert.impl.CharacterConverter;
import cn.hutool.core.convert.impl.CharsetConverter;
import cn.hutool.core.convert.impl.ClassConverter;
import cn.hutool.core.convert.impl.CollectionConverter;
import cn.hutool.core.convert.impl.CurrencyConverter;
import cn.hutool.core.convert.impl.DateConverter;
import cn.hutool.core.convert.impl.DurationConverter;
import cn.hutool.core.convert.impl.EnumConverter;
import cn.hutool.core.convert.impl.LocaleConverter;
import cn.hutool.core.convert.impl.MapConverter;
import cn.hutool.core.convert.impl.NumberConverter;
import cn.hutool.core.convert.impl.OptionalConverter;
import cn.hutool.core.convert.impl.PathConverter;
import cn.hutool.core.convert.impl.PeriodConverter;
import cn.hutool.core.convert.impl.PrimitiveConverter;
import cn.hutool.core.convert.impl.ReferenceConverter;
import cn.hutool.core.convert.impl.StackTraceElementConverter;
import cn.hutool.core.convert.impl.StringConverter;
import cn.hutool.core.convert.impl.TemporalAccessorConverter;
import cn.hutool.core.convert.impl.TimeZoneConverter;
import cn.hutool.core.convert.impl.URIConverter;
import cn.hutool.core.convert.impl.URLConverter;
import cn.hutool.core.convert.impl.UUIDConverter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.ServiceLoaderUtil;
import cn.hutool.core.util.TypeUtil;

import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Period;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Collection;
import java.util.Currency;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 转换器登记中心
 * <p>
 * 将各种类型Convert对象放入登记中心,通过convert方法查找目标类型对应的转换器,将被转换对象转换之。
 * </p>
 * <p>
 * 在此类中,存放着默认转换器和自定义转换器,默认转换器是Hutool中预定义的一些转换器,自定义转换器存放用户自定的转换器。
 * </p>
 *
 * @author Looly
 */
public class ConverterRegistry implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 默认类型转换器
	 */
	private Map<Type, Converter<?>> defaultConverterMap;
	/**
	 * 用户自定义类型转换器
	 */
	private volatile Map<Type, Converter<?>> customConverterMap;

	/**
	 * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
	 */
	private static class SingletonHolder {
		/**
		 * 静态初始化器,由JVM来保证线程安全
		 */
		private static final ConverterRegistry INSTANCE = new ConverterRegistry();
	}

	/**
	 * 获得单例的 ConverterRegistry
	 *
	 * @return ConverterRegistry
	 */
	public static ConverterRegistry getInstance() {
		return SingletonHolder.INSTANCE;
	}

	/**
	 * 登记自定义转换器
	 *
	 * @param type           转换的目标类型
	 * @param converterClass 转换器类,必须有默认构造方法
	 * @return ConverterRegistry
	 */
	public ConverterRegistry putCustom(Type type, Class<? extends Converter<?>> converterClass) {
		return putCustom(type, ReflectUtil.newInstance(converterClass));
	}

	/**
	 * 登记自定义转换器
	 *
	 * @param type      转换的目标类型
	 * @param converter 转换器
	 * @return ConverterRegistry
	 */
	public ConverterRegistry putCustom(Type type, Converter<?> converter) {
		if (null == customConverterMap) {
			synchronized (this) {
				if (null == customConverterMap) {
					customConverterMap = new ConcurrentHashMap<>();
				}
			}
		}
		customConverterMap.put(type, converter);
		return this;
	}

	/**
	 * 构造
	 */
	public ConverterRegistry() {
		defaultConverter();
		putCustomBySpi();
	}

	/**
	 * 使用SPI加载转换器
	 */
	private void putCustomBySpi() {
		ServiceLoaderUtil.load(Converter.class).forEach(converter -> {
			try {
				Type type = TypeUtil.getTypeArgument(ClassUtil.getClass(converter));
				if(null != type){
					putCustom(type, converter);
				}
			} catch (Exception e) {
				// 忽略注册失败的
			}
		});
	}


	/**
	 * 获得转换器<br>
	 *
	 * @param <T>           转换的目标类型
	 * @param type          类型
	 * @param isCustomFirst 是否自定义转换器优先
	 * @return 转换器
	 */
	public <T> Converter<T> getConverter(Type type, boolean isCustomFirst) {
		Converter<T> converter;
		if (isCustomFirst) {
			converter = this.getCustomConverter(type);
			if (null == converter) {
				converter = this.getDefaultConverter(type);
			}
		} else {
			converter = this.getDefaultConverter(type);
			if (null == converter) {
				converter = this.getCustomConverter(type);
			}
		}
		return converter;
	}

	/**
	 * 获得默认转换器
	 *
	 * @param <T>  转换的目标类型(转换器转换到的类型)
	 * @param type 类型
	 * @return 转换器
	 */
	@SuppressWarnings("unchecked")
	public <T> Converter<T> getDefaultConverter(Type type) {
		return (null == defaultConverterMap) ? null : (Converter<T>) defaultConverterMap.get(type);
	}

	/**
	 * 获得自定义转换器
	 *
	 * @param <T>  转换的目标类型(转换器转换到的类型)
	 * @param type 类型
	 * @return 转换器
	 */
	@SuppressWarnings("unchecked")
	public <T> Converter<T> getCustomConverter(Type type) {
		return (null == customConverterMap) ? null : (Converter<T>) customConverterMap.get(type);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T>           转换的目标类型(转换器转换到的类型)
	 * @param type          类型目标
	 * @param value         被转换值
	 * @param defaultValue  默认值
	 * @param isCustomFirst 是否自定义转换器优先
	 * @return 转换后的值
	 * @throws ConvertException 转换器不存在
	 */
	@SuppressWarnings("unchecked")
	public <T> T convert(Type type, Object value, T defaultValue, boolean isCustomFirst) throws ConvertException {
		if (TypeUtil.isUnknown(type) && null == defaultValue) {
			// 对于用户不指定目标类型的情况,返回原值
			return (T) value;
		}
		if (ObjectUtil.isNull(value)) {
			return defaultValue;
		}
		if (TypeUtil.isUnknown(type)) {
			type = defaultValue.getClass();
		}

		if (type instanceof TypeReference) {
			type = ((TypeReference<?>) type).getType();
		}

		// 标准转换器
		final Converter<T> converter = getConverter(type, isCustomFirst);
		if (null != converter) {
			return converter.convert(value, defaultValue);
		}

		Class<T> rowType = (Class<T>) TypeUtil.getClass(type);
		if (null == rowType) {
			if (null != defaultValue) {
				rowType = (Class<T>) defaultValue.getClass();
			} else {
				// 无法识别的泛型类型,按照Object处理
				return (T) value;
			}
		}


		// 特殊类型转换,包括Collection、Map、强转、Array等
		final T result = convertSpecial(type, rowType, value, defaultValue);
		if (null != result) {
			return result;
		}

		// 尝试转Bean
		if (BeanUtil.isBean(rowType)) {
			return new BeanConverter<T>(type).convert(value, defaultValue);
		}

		// 无法转换
		throw new ConvertException("Can not Converter from [{}] to [{}]", value.getClass().getName(), type.getTypeName());
	}

	/**
	 * 转换值为指定类型<br>
	 * 自定义转换器优先
	 *
	 * @param <T>          转换的目标类型(转换器转换到的类型)
	 * @param type         类型
	 * @param value        值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 * @throws ConvertException 转换器不存在
	 */
	public <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
		return convert(type, value, defaultValue, true);
	}

	/**
	 * 转换值为指定类型
	 *
	 * @param <T>   转换的目标类型(转换器转换到的类型)
	 * @param type  类型
	 * @param value 值
	 * @return 转换后的值,默认为{@code null}
	 * @throws ConvertException 转换器不存在
	 */
	public <T> T convert(Type type, Object value) throws ConvertException {
		return convert(type, value, null);
	}

	// ----------------------------------------------------------- Private method start

	/**
	 * 特殊类型转换<br>
	 * 包括:
	 *
	 * <pre>
	 * Collection
	 * Map
	 * 强转(无需转换)
	 * 数组
	 * </pre>
	 *
	 * @param <T>          转换的目标类型(转换器转换到的类型)
	 * @param type         类型
	 * @param value        值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 */
	@SuppressWarnings("unchecked")
	private <T> T convertSpecial(Type type, Class<T> rowType, Object value, T defaultValue) {
		if (null == rowType) {
			return null;
		}

		// 集合转换(不可以默认强转)
		if (Collection.class.isAssignableFrom(rowType)) {
			final CollectionConverter collectionConverter = new CollectionConverter(type);
			return (T) collectionConverter.convert(value, (Collection<?>) defaultValue);
		}

		// Map类型(不可以默认强转)
		if (Map.class.isAssignableFrom(rowType)) {
			final MapConverter mapConverter = new MapConverter(type);
			return (T) mapConverter.convert(value, (Map<?, ?>) defaultValue);
		}

		// 默认强转
		if (rowType.isInstance(value)) {
			return (T) value;
		}

		// 枚举转换
		if (rowType.isEnum()) {
			return (T) new EnumConverter(rowType).convert(value, defaultValue);
		}

		// 数组转换
		if (rowType.isArray()) {
			final ArrayConverter arrayConverter = new ArrayConverter(rowType);
			return (T) arrayConverter.convert(value, defaultValue);
		}

		// 表示非需要特殊转换的对象
		return null;
	}

	/**
	 * 注册默认转换器
	 *
	 * @return 转换器
	 */
	private ConverterRegistry defaultConverter() {
		defaultConverterMap = new ConcurrentHashMap<>();

		// 原始类型转换器
		defaultConverterMap.put(int.class, new PrimitiveConverter(int.class));
		defaultConverterMap.put(long.class, new PrimitiveConverter(long.class));
		defaultConverterMap.put(byte.class, new PrimitiveConverter(byte.class));
		defaultConverterMap.put(short.class, new PrimitiveConverter(short.class));
		defaultConverterMap.put(float.class, new PrimitiveConverter(float.class));
		defaultConverterMap.put(double.class, new PrimitiveConverter(double.class));
		defaultConverterMap.put(char.class, new PrimitiveConverter(char.class));
		defaultConverterMap.put(boolean.class, new PrimitiveConverter(boolean.class));

		// 包装类转换器
		defaultConverterMap.put(Number.class, new NumberConverter());
		defaultConverterMap.put(Integer.class, new NumberConverter(Integer.class));
		defaultConverterMap.put(AtomicInteger.class, new NumberConverter(AtomicInteger.class));// since 3.0.8
		defaultConverterMap.put(Long.class, new NumberConverter(Long.class));
		defaultConverterMap.put(AtomicLong.class, new NumberConverter(AtomicLong.class));// since 3.0.8
		defaultConverterMap.put(Byte.class, new NumberConverter(Byte.class));
		defaultConverterMap.put(Short.class, new NumberConverter(Short.class));
		defaultConverterMap.put(Float.class, new NumberConverter(Float.class));
		defaultConverterMap.put(Double.class, new NumberConverter(Double.class));
		defaultConverterMap.put(Character.class, new CharacterConverter());
		defaultConverterMap.put(Boolean.class, new BooleanConverter());
		defaultConverterMap.put(AtomicBoolean.class, new AtomicBooleanConverter());// since 3.0.8
		defaultConverterMap.put(BigDecimal.class, new NumberConverter(BigDecimal.class));
		defaultConverterMap.put(BigInteger.class, new NumberConverter(BigInteger.class));
		defaultConverterMap.put(CharSequence.class, new StringConverter());
		defaultConverterMap.put(String.class, new StringConverter());

		// URI and URL
		defaultConverterMap.put(URI.class, new URIConverter());
		defaultConverterMap.put(URL.class, new URLConverter());

		// 日期时间
		defaultConverterMap.put(Calendar.class, new CalendarConverter());
		defaultConverterMap.put(java.util.Date.class, new DateConverter(java.util.Date.class));
		defaultConverterMap.put(DateTime.class, new DateConverter(DateTime.class));
		defaultConverterMap.put(java.sql.Date.class, new DateConverter(java.sql.Date.class));
		defaultConverterMap.put(java.sql.Time.class, new DateConverter(java.sql.Time.class));
		defaultConverterMap.put(java.sql.Timestamp.class, new DateConverter(java.sql.Timestamp.class));

		// 日期时间 JDK8+(since 5.0.0)
		defaultConverterMap.put(TemporalAccessor.class, new TemporalAccessorConverter(Instant.class));
		defaultConverterMap.put(Instant.class, new TemporalAccessorConverter(Instant.class));
		defaultConverterMap.put(LocalDateTime.class, new TemporalAccessorConverter(LocalDateTime.class));
		defaultConverterMap.put(LocalDate.class, new TemporalAccessorConverter(LocalDate.class));
		defaultConverterMap.put(LocalTime.class, new TemporalAccessorConverter(LocalTime.class));
		defaultConverterMap.put(ZonedDateTime.class, new TemporalAccessorConverter(ZonedDateTime.class));
		defaultConverterMap.put(OffsetDateTime.class, new TemporalAccessorConverter(OffsetDateTime.class));
		defaultConverterMap.put(OffsetTime.class, new TemporalAccessorConverter(OffsetTime.class));
		defaultConverterMap.put(Period.class, new PeriodConverter());
		defaultConverterMap.put(Duration.class, new DurationConverter());

		// Reference
		defaultConverterMap.put(WeakReference.class, new ReferenceConverter(WeakReference.class));// since 3.0.8
		defaultConverterMap.put(SoftReference.class, new ReferenceConverter(SoftReference.class));// since 3.0.8
		defaultConverterMap.put(AtomicReference.class, new AtomicReferenceConverter());// since 3.0.8

		//AtomicXXXArray,since 5.4.5
		defaultConverterMap.put(AtomicIntegerArray.class, new AtomicIntegerArrayConverter());
		defaultConverterMap.put(AtomicLongArray.class, new AtomicLongArrayConverter());

		// 其它类型
		defaultConverterMap.put(Class.class, new ClassConverter());
		defaultConverterMap.put(TimeZone.class, new TimeZoneConverter());
		defaultConverterMap.put(Locale.class, new LocaleConverter());
		defaultConverterMap.put(Charset.class, new CharsetConverter());
		defaultConverterMap.put(Path.class, new PathConverter());
		defaultConverterMap.put(Currency.class, new CurrencyConverter());// since 3.0.8
		defaultConverterMap.put(UUID.class, new UUIDConverter());// since 4.0.10
		defaultConverterMap.put(StackTraceElement.class, new StackTraceElementConverter());// since 4.5.2
		defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0

		return this;
	}
	// ----------------------------------------------------------- Private method end
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
hutool工具类提供了丰富的日期方法。其中包括: 1. 日期时间工具类(DateUtil)提供了以下功能: - 日期、long、calendar之间的相互转换; - 字符串转日期; - 格式化日期输出; - 获取Date对象的某个部分; - 开始时间和结束时间(可以按日、按周、按月); - 日期时间偏移; - 日期时间差; - 格式化时间差; - 星座和属相等其他功能。 2. Convert类型转换工具类提供了以下功能: - Java常见类型转换,包括转换字符串、转换为指定类型数组、转换为日期对象、转换为集合等。 以上是hutool工具类中关于日期的一些常用方法。你可以根据需要使用这些方法来简化日期的处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [hutool 工具类](https://download.csdn.net/download/LiHaoYang11/12153632)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [HuTool工具类实用技巧:从常用方法入手](https://blog.csdn.net/qijing19991210/article/details/127884732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值