开发者

Why java.lang.StringEncoding.encode ignore given charset to use default one?

My app default encoding is set to "UTF-8" (using -Dfile.encoding=UTF-8 on startup). When I use the String class method "getBytes(String charsetName)" with charset="ISO-8859-1", it appears that StringCoding.encode finally uses the default charset (UTF-8) instead of the given one (ISO-8859-1).

For an unknown reason, I can debug step by step on this method, but I'm not able to inspect inner elements value (only parameters which are named arg0, arg1 ...)

In java 1.6.10, StringCoding.encode is written :

static byte[] encode(String charsetName, char[] ca, int off, int len)
    throws UnsupportedEncodingException
{
    StringEncoder se = (StringEncoder)deref(enco开发者_如何转开发der);
    String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
    if ((se == null) || !(csn.equals(se.requestedCharsetName())
                  || csn.equals(se.charsetName()))) {
        se = null;
        try {
        Charset cs = lookupCharset(csn);
        if (cs != null)
            se = new StringEncoder(cs, csn);
        } catch (IllegalCharsetNameException x) {}
        if (se == null)
            throw new UnsupportedEncodingException (csn);
        set(encoder, se);
    }
    return se.encode(ca, off, len);
}

With step by step debug, I never enter the if block and then no new StringEncoder with my ISO-8859-1 charset is created. Finally, the Charset.defaultCharset() method is called.

Any clues ? Thanks


If you're not getting into the if block, then this expression must be false

(se == null) || !(csn.equals(se.requestedCharsetName())
                  || csn.equals(se.charsetName()))

That means that:

  • se mustn't be null
  • The second part must be true before hitting the !, so one of these subexpressions must be true:
    • csn.equals(se.requestedCharsetName())
    • csn.equals(se.charsetName())

In other words, se is already appropriate for the charset name you've requested.

This isn't using the "default" encoding for the VM; it's using the encoder last used in this thread.

I highly doubt you've found a JRE bug - it looks okay to me. So what caused you to debug into this to start with? Can you provide a short but complete program which demonstrates an error using this? Something encoding to the wrong bytes?


You need to change the

-Dfile.ecoding=UTF-8 to

-Dfile.encoding=UTF-8


encode should never ignore the given charset to revert to the one given in -Dfile.encoding.

It does. As does decode by the way, even if the source does show that it finds the charset, and sets it in the line:

set(encoder, se);

Neither encode or decode are threadsafe, so the value is bound to be overridden by the system default, it may be before or after decode manages to use the set value though.

Imho, this is a bug in the JRE. True the OP had a typo, but that does not change the fact that if you ask String to decode a byte array to UTF-8, it should always return UTF-8, and not silently fall back to something else.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜