Pain Points

In Java development, we face various issues with type conversions, especially when obtaining user parameters from the command line or parameters from HttpRequest, etc. These parameters can have various types, and how do we convert them? The common practice is to convert them to a String first, and then call a parseXXX method, also bearing the risk of conversion failure and having to add a try-catch layer. This small process mixed in business code can look very ugly and bloated.

Convert Class

The Convert class can be said to be a utility method class, which encapsulates conversions for common Java types to simplify type conversions. Most methods in the Convert class are toXXX, with Object as a parameter, which can convert any possible type to a specified type. It also supports a second parameter, defaultValue, which is used to return a default value when conversion fails.

Conversions for Common Java Types

  1. Converting to a String:
int a = 1;
//aStr is "1"
String aStr = Convert.toStr(a);

long[] b = {1,2,3,4,5};
//bStr is: "[1, 2, 3, 4, 5]"
String bStr = Convert.toStr(b);
  1. Converting to a Specified Type Array:
String[] b = { "1", "2", "3", "4" };
//The result is an Integer array
Integer[] intArray = Convert.toIntArray(b);

long[] c = {1,2,3,4,5};
//The result is an Integer array
Integer[] intArray2 = Convert.toIntArray(c);
  1. Converting to a Date Object:
String a = "2017-05-06";
Date value = Convert.toDate(a);
  1. Converting to a Collection:
Object[] a = {"a", "你", "好", "", 1};
List<?> list = Convert.convert(List.class, a);
//Starting from 4.1.11, you can use it like this:
List<?> list = Convert.toList(a);

Other Type Conversions

  1. Standard Types: Through the Convert.convert(Class<T>, Object) method, any type can be converted to a specified type. Hutool preset many type conversions,such as converting to URI、URL、Calendar,etc. These types of conversions rely on the ConverterRegistry class. We can customize some type conversions through this class and the Converter interface. For more details on how to use it, please refer to the section on “Customizing Type Conversions”.
  2. Generic Types: Through the convert(TypeReference<T> reference, Object value) method, you can create your own TypeReference object and use it for nested generic type conversion. For example, if you want to convert an object to a List<String> type, passing the standard Class as a parameter will not work. In this case, you can do it like this:
Object[] a = { "a", "你", "好", "", 1 };
List<String> list = Convert.convert(new TypeReference<List<String>>() {}, a);

Instantiate a generic type through TypeReference, and then convert the object to the target type we want.

Half-width and full-width conversion

These two methods are very useful in the unification of many texts, mainly for the conversion of punctuation marks between half-width and full-width.

Half-width to full-width:

String a = "123456789";

// Result: "123456789"
String sbc = Convert.toSBC(a);

Full-width to half-width:

String a = "123456789";

// Result: "123456789"
String dbc = Convert.toDBC(a);

Hexadecimal (Hex)

When it comes to encryption and decryption, as well as the transmission of Chinese strings (such as form submission), hexadecimal conversion, also known as Hex conversion, is often used. Hutool has a dedicated HexUtil utility class for this purpose. Considering that hexadecimal conversion is also a part of conversion, its methods are also placed in the Convert class for easier understanding and lookup. The usage is equally simple:

Convert to hexadecimal (Hex) string:

String a = "我是一个小小的可爱的字符串";

// Result: "e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2"
String hex = Convert.toHex(a, CharsetUtil.CHARSET_UTF_8);

Convert hexadecimal (Hex) string to ordinary string:

String hex = "e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2";

// Result: "我是一个小小的可爱的字符串"
String raw = Convert.hexStrToStr(hex, CharsetUtil.CHARSET_UTF_8);

// Note: After 4.1.11, hexStrToStr will be renamed to hexToStr
String raw = Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8);

The encoding object must be passed in because the string involves encoding issues. UTF-8 encoding is used here. The toHex method also supports passing in byte[], and you can use the hexToBytes method to convert hexadecimal to byte[] as well.

Unicode and string conversion

Similar to hexadecimal, the Convert class can also easily convert between strings and Unicode:

String a = "我是一个小小的可爱的字符串";

// Result: "\\u6211\\u662f\\u4e00\\u4e2a\\u5c0f\\u5c0f\\u7684\\u53ef\\u7231\\u7684\\u5b57\\u7b26\\u4e32" 
String unicode = Convert.strToUnicode(a);

// Result: "我是一个小小的可爱的字符串"
String raw = Convert.unicodeToStr(unicode);

This is very familiar, right? If you have written Chinese in a properties file before, you would understand the importance of this method.

Encoding conversion

When receiving forms, we are often troubled by Chinese garbled characters. Most of the time, this is because the data was decoded using an incorrect encoding method. The Convert.convertCharset method comes in handy here, as it can convert garbled characters to the correct encoding method:

String a = "我不是乱码";
// After conversion, result is garbled characters
String result = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
String raw = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Assert.assertEquals(raw, a);

Note: After testing, converting from UTF-8 encoding to GBK decoding, then from GBK encoding to UTF-8 decoding may cause some Chinese characters to fail to convert correctly.

Time unit conversion

The Convert.convertTime method is mainly used for converting time. For example, given a large number of milliseconds, I want to find out how many minutes this corresponds to:

long a = 4535345;

// Result is: 75
long minutes = Convert.convertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES);

Converting currency amounts to upper case

To convert currency amounts to upper case, use Convert.digitToChinese. Here’s an example:

double a = 67556.32;

// Result is: "陆万柒仟伍佰伍拾陆元叁角贰分"
String digitUppercase = Convert.digitToChinese(a);

Note Conversion to upper case is accurate to the cent (the two decimal places), any subsequent digits are ignored.

Number conversion

  1. Converting numbers to English
// ONE HUNDRED AND CENTS TWENTY THREE ONLY
String format = Convert.numberToWord(100.23);
  1. Simplifying numbers
// 1.2k
String format1 = Convert.numberToSimple(1200, false);
  1. Converting numbers to Chinese Number conversion to Chinese, retaining only two decimal places:
// 一万零八百八十九点七二
String f1 = Convert.numberToChinese(10889.72356, false);

// Using amount in upper case format
// 壹万贰仟陆佰伍拾叁
String f1 = Convert.numberToChinese(12653, true);
  1. Converting Chinese numbers to numbers
// 1012
String f1 = Convert.numberToChinese("一千零一十二");

Converting primitive types and wrapper classes

Sometimes it’s necessary to convert between primitive types and their corresponding wrapper classes (e.g., Integer.class and int.class). Here’s how we can do this:

// Unwrap the wrapper class
Class<?> wrapClass = Integer.class;

// Result is: int.class
Class<?> unWraped = Convert.unWrap(wrapClass);

// Wrap the primitive class
Class<?> primitiveClass = long.class;

// Result is: Long.class
Class<?> wraped = Convert.wrap(primitiveClass);