21

在库方法中调用 String.getBytes("UTF-8") 时处理UnsupportedEncodingException的推荐方法是什么?

如果我正确阅读http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html,UTF-8编码应该始终可用,这让我相信没有将此异常传递给库的使用者的原因(即,throws在方法签名中添加一个子句)。似乎任何使 UTF-8 编码设施不可用的故障模式都是灾难性的,导致我编写了这个处理程序:

    try
    {
        ....
        return "blah".getBytes("UTF-8");
    }
    catch (UnsupportedEncodingException e)
    {
        // we're assuming UTF-8 encoding is always available.
        // see
        // http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html
        e.printStackTrace();
        return null; //prevent compile-time "method must return a result" errors
    }

是否存在此代码段无法解决的故障模式?

4

3 回答 3

53

你知道我做什么吗?

return "blah".getBytes( Charset.forName( "UTF-8" ) );

这个不会引发检查异常。

更新:从 Java 1.7 开始,我们有了StandardCharsets

return "blah".getBytes( StandardCharsets.UTF_8 );
于 2012-05-25T04:40:04.347 回答
3

我在尝试确定 UTF-8 是否始终可用时遇到了这个问题。所以谢谢你的链接。

我同意,在使用保证可用的特定字符集进行编码和解码时,无需抛出已检查异常。如果字符集是传入的变量,我可能会抛出 UnsupportedEncodingException。

这就是我在一段类似的 Android 代码中所做的:

public static String encode(String input) {
    try {
        return URLEncoder.encode(input, CharEncoding.UTF_8);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    }
}

CharEncoding.UTF_8只是“UTF-8”的 Apache Commons 的字符串常量。

Judge Mental 的使用建议StandardCharsets.UTF_8很棒,但对于我们这些从事 Android 开发的人来说,它仅适用于 SDK 19 (KitKat) 及更高版本。

于 2015-08-07T20:03:54.420 回答
1

如果您使用 Lombok,则可以使用 @SneakyThrows 注解来避免这种情况。

从龙目岛文档:

“@SneakyThrows 可用于偷偷抛出已检查的异常,而无需在方法的 throws 子句中实际声明这一点。

  • 一个“不可能”的例外。例如, new String(someByteArray, "UTF-8"); 声明它可以抛出 UnsupportedEncodingException 但根据 JVM 规范,UTF-8 必须始终可用。当您使用 String 对象时,这里的 UnsupportedEncodingException 与 ClassNotFoundError 的可能性差不多,而且您也没有捕捉到那些!"

https://projectlombok.org/features/SneakyThrows

于 2021-01-25T21:16:26.693 回答