URL解码:Java中的UnsupportedEncodingException

54

根据文档,我理解的是只有当我在URLDecoder.decode(String, String)方法的第二个参数中指定了错误的编码时,才会抛出UnsupportedEncodingException异常。是这样吗?我需要知道会抛出这个异常的情况。

基本上,我在我的一个函数中有这段代码:

if (keyVal.length == 2) {
    try {
        value = URLDecoder.decode(
            keyVal[1],
            "UTF-8");
    } catch (UnsupportedEncodingException e) {
          // Will it ever be thrown?
    }
}

因为我明确提到了“UTF-8”,所以是否有可能抛出此异常?在catch块中需要做些什么吗?或者,如果我的理解完全错误,请告诉我。

4个回答

56

除非你的JVM出现了一些根本性的问题,否则不可能发生这种情况。但我认为你应该这样写:

try {
    value = URLDecoder.decode(keyVal[1], "UTF-8");
} catch (UnsupportedEncodingException e) {
    throw new AssertionError("UTF-8 is unknown");
    // or 'throw new AssertionError("Impossible things are happening today. " +
    //                              "Consider buying a lottery ticket!!");'
}
这样做的代价只是一些永远不会被执行的代码和一个永远不会被使用的字符串常量。这是为了防止您可能误读/误解JavaDocs(在这种情况下您没有...)或规范可能会更改(在这种情况下不会...)的可能性而采取的小小代价。

2
JVM 可能会出现哪些实际的破坏性例子? - Pacerier
1
@Pacerier - 我想不出任何方法。你可能需要修改“rt.jar”文件(或更糟),才能打破这个限制。因此,从理论上讲是可能的......但除非你正在创建/使用实验性JVM,否则你不太可能遇到这种情况。 - Stephen C
1
这个异常被检查的原因是什么? - Tomasz Nocoń
大概是因为设计者认为这是一个典型应用程序应该处理的错误条件。 (事后看来,这可能是个错误,但如果修复它会破坏二进制兼容性。) - Stephen C
1
另一个问题是只有在使用“UTF-8”编码时才能保证不会抛出异常。对于其他编码名称...可能会发生异常,将异常检查是一个合理的决定。也许解决方案是添加一个URLDecoder.decodeUTF8(方法,根本不会抛出异常。 - Stephen C

16

这是因为选择使UnsupportedEncodingException成为检查异常的奇怪选择。不,它不会被抛出。

我通常采用以下方法:

} catch (UnsupportedEncodingException e) {
  throw new AssertionError("UTF-8 not supported");
}

6

在你的特殊情况下 - 不会抛出异常。除非你在不支持“UTF-8”的Java运行时中执行代码。


1
这样的运行时不应该存在 - 至少在JDK 1.6中,UTF-8是标准字符集。http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html - Mat
3
@Mat - 我也相信这一点,但是..Oracle并不是Java运行时的唯一供应商。 Java语言规范没有提到必须支持任何编码(除了:UTF-16作为char指定的编码)。 - Andreas Dolk
哇,谢谢。我以为它会这样做,而且Javadoc似乎暗示着这一点,但你是正确的,这在JLS中并没有规定。 - Mat
1
Java文档是规范的吗?你有这个说法的参考资料吗?老实说,我不相信一个人必须实现JLS和所有Java文档细节(顺便问一下,是哪个版本的?)才能获得证书。 - Andreas Dolk
如果您想获得认证,那么它们就是规范性的。如果您的实现未经过认证,则无法获得在您的“Java”实现中使用Java商标的许可。如果您确实使用了它们,那么请准备好接收Oracle律师的来信。(这就是为什么没有成千上万个混淆的Java分支都带有“Java”名称的原因。) - Stephen C
显示剩余2条评论

4
为了回答一个老问题,向新读者们说明一下:
Java 11现在有一个不会抛出异常的 URLDecoder.decode(String, Charset); 方法。因此您根本不需要使用try-catch块。只需执行以下操作:
URLDecoder.decode(keyVal[1], StandardCharsets.UTF_8);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接